JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> location, configured codec
*/
public JsonParser asParser(JsonParser src)
{
Parser p = new Parser(_first, src.getCodec(), _hasNativeTypeIds, _hasNativeObjectIds);
p.setLocation(src.getTokenLocation());
return p;
}
/*
/**********************************************************
/* Additional accessors
/**********************************************************
*/
public JsonToken firstToken() {
if (_first != null) {
return _first.type(0);
}
return null;
}
/*
/**********************************************************
/* Other custom methods not needed for implementing interfaces
/**********************************************************
*/
/**
* Helper method that will append contents of given buffer into this
* buffer.
* Not particularly optimized; can be made faster if there is need.
*
* @return This buffer
*/
@SuppressWarnings("resource")
public TokenBuffer append(TokenBuffer other)
throws IOException, JsonGenerationException
{
// Important? If source has native ids, need to store
if (!_hasNativeTypeIds) {
_hasNativeTypeIds = other.canWriteTypeId();
}
if (!_hasNativeObjectIds) {
_hasNativeObjectIds = other.canWriteObjectId();
}
_mayHaveNativeIds = _hasNativeTypeIds | _hasNativeObjectIds;
JsonParser jp = other.asParser();
while (jp.nextToken() != null) {
copyCurrentStructure(jp);
}
return this;
}
/**
* Helper method that will write all contents of this buffer
* using given {@link JsonGenerator}.
*<p>
* Note: this method would be enough to implement
* <code>JsonSerializer</code> for <code>TokenBuffer</code> type;
* but we can not have upwards
* references (from core to mapper package); and as such we also
* can not take second argument.
*/
public void serialize(JsonGenerator jgen)
throws IOException, JsonGenerationException
{
Segment segment = _first;
int ptr = -1;
final boolean checkIds = _mayHaveNativeIds;
boolean hasIds = checkIds && (segment.hasIds());
while (true) {
if (++ptr >= Segment.TOKENS_PER_SEGMENT) {
ptr = 0;
segment = segment.next();
if (segment == null) break;
hasIds = checkIds && (segment.hasIds());
}
JsonToken t = segment.type(ptr);
if (t == null) break;
if (hasIds) {
Object id = segment.findObjectId(ptr);
if (id != null) {
jgen.writeObjectId(id);
}
id = segment.findTypeId(ptr);
if (id != null) {
jgen.writeTypeId(id);
}
}
// Note: copied from 'copyCurrentEvent'...
switch (t) {
case START_OBJECT:
jgen.writeStartObject();
break;
case END_OBJECT:
jgen.writeEndObject();
break;
case START_ARRAY:
jgen.writeStartArray();
break;
case END_ARRAY:
jgen.writeEndArray();
break;
case FIELD_NAME:
{
// 13-Dec-2010, tatu: Maybe we should start using different type tokens to
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> reduce casting?
Object ob = segment.get(ptr);
if (ob instanceof SerializableString) {
jgen.writeFieldName((SerializableString) ob);
} else {
jgen.writeFieldName((String) ob);
}
}
break;
case VALUE_STRING:
{
Object ob = segment.get(ptr);
if (ob instanceof SerializableString) {
jgen.writeString((SerializableString) ob);
} else {
jgen.writeString((String) ob);
}
}
break;
case VALUE_NUMBER_INT:
{
Object n = segment.get(ptr);
if (n instanceof Integer) {
jgen.writeNumber((Integer) n);
} else if (n instanceof BigInteger) {
jgen.writeNumber((BigInteger) n);
} else if (n instanceof Long) {
jgen.writeNumber((Long) n);
} else if (n instanceof Short) {
jgen.writeNumber((Short) n);
} else {
jgen.writeNumber(((Number) n).intValue());
}
}
break;
case VALUE_NUMBER_FLOAT:
{
Object n = segment.get(ptr);
if (n instanceof Double) {
jgen.writeNumber(((Double) n).doubleValue());
} else if (n instanceof BigDecimal) {
jgen.writeNumber((BigDecimal) n);
} else if (n instanceof Float) {
jgen.writeNumber(((Float) n).floatValue());
} else if (n == null) {
jgen.writeNull();
} else if (n instanceof String) {
jgen.writeNumber((String) n);
} else {
throw new JsonGenerationException("Unrecognized value type for VALUE_NUMBER_FLOAT: "+n.getClass().getName()+", can not serialize");
}
}
break;
case VALUE_TRUE:
jgen.writeBoolean(true);
break;
case VALUE_FALSE:
jgen.writeBoolean(false);
break;
sb.append("NativeObjectIds=").append(_hasNativeObjectIds).append(",");
*/
JsonParser jp = asParser();
int count = 0;
final boolean hasNativeIds = _hasNativeTypeIds || _hasNativeObjectIds;
while (true) {
JsonToken t;
try {
t = jp.nextToken();
if (t == null) break;
if (hasNativeIds) {
_appendNativeIds(sb);
}
if (count < MAX_COUNT) {
if (count > 0) {
sb.append(", ");
}
sb.append(t.toString());
if (t == JsonToken.FIELD_NAME) {
sb.append('(');
sb.append(jp.getCurrentName());
sb.append(')');
}
}
} catch (IOException ioe) { // should never occur
throw new IllegalStateException(ioe);
}
++count;
}
if (count >= MAX_COUNT) {
sb.append(" ... (truncated ").append(count-MAX_COUNT).append(" entries)");
}
sb.append(']');
return sb.toString();
}
private final void _appendNativeIds(StringBuilder sb)
{
Object objectId = _last.findObjectId(_appendAt-1);
if (objectId != null) {
sb
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>.append("[objectId=").append(String.valueOf(objectId)).append(']');
}
Object typeId = _last.findTypeId(_appendAt-1);
if (typeId != null) {
sb.append("[typeId=").append(String.valueOf(typeId)).append(']');
}
}
/*
/**********************************************************
/* JsonGenerator implementation: configuration
/**********************************************************
*/
@Override
public JsonGenerator enable(Feature f) {
_generatorFeatures |= f.getMask();
return this;
}
@Override
public JsonGenerator disable(Feature f) {
_generatorFeatures &= ~f.getMask();
return this;
}
//public JsonGenerator configure(SerializationFeature f, boolean state) { }
@Override
public boolean isEnabled(Feature f) {
return (_generatorFeatures & f.getMask()) != 0;
}
@Override
public int getFeatureMask() {
return _generatorFeatures;
}
@Override
public JsonGenerator setFeatureMask(int mask) {
_generatorFeatures = mask;
return this;
}
@Override
public JsonGenerator useDefaultPrettyPrinter() {
// No-op: we don't indent
return this;
}
@Override
public JsonGenerator setCodec(ObjectCodec oc) {
_objectCodec = oc;
return this;
}
@Override
public ObjectCodec getCodec() { return _objectCodec; }
@Override
public final JsonWriteContext getOutputContext() { return _writeContext; }
/*
/**********************************************************
/* JsonGenerator implementation: capability introspection
/**********************************************************
*/
/**
* Since we can efficiently store <code>byte[]</code>, yes.
*/
@Override
public boolean canWriteBinaryNatively() {
return true;
}
/*
/**********************************************************
/* JsonGenerator implementation: low-level output handling
/**********************************************************
*/
@Override
public void flush() throws IOException { /* NOP */ }
@Override
public void close() throws IOException {
_closed = true;
}
@Override
public boolean isClosed() { return _closed; }
/*
/**********************************************************
/* JsonGenerator implementation: write methods, structural
/**********************************************************
*/
@Override
public final void writeStartArray()
throws IOException, JsonGenerationException
{
_append(JsonToken.START_ARRAY);
_writeContext = _writeContext.createChildArrayContext();
}
@Override
public final void writeEndArray()
throws IOException, JsonGenerationException
{
_append(JsonToken.END_ARRAY);
// Let's allow unbalanced tho... i.e. not run out of root level, ever
JsonWriteContext c = _writeContext.getParent();
if (c != null) {
_writeContext = c;
}
}
@Override
public final void writeStartObject()
throws IOException, JsonGenerationException
{
_append(JsonToken.START_OBJECT);
_writeContext = _writeContext.createChildObjectContext();
}
@Override
public final void writeEndObject()
throws IOException, JsonGenerationException
{
_append(JsonToken.END_OBJECT);
// Let's allow unbalanced tho... i.e. not run out of root level, ever
JsonWriteContext c = _writeContext.getParent();
if (c !=
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> null) {
_writeContext = c;
}
}
@Override
public final void writeFieldName(String name)
throws IOException, JsonGenerationException
{
_append(JsonToken.FIELD_NAME, name);
_writeContext.writeFieldName(name);
}
@Override
public void writeFieldName(SerializableString name)
throws IOException, JsonGenerationException
{
_append(JsonToken.FIELD_NAME, name);
_writeContext.writeFieldName(name.getValue());
}
/*
/**********************************************************
/* JsonGenerator implementation: write methods, textual
/**********************************************************
*/
@Override
public void writeString(String text) throws IOException,JsonGenerationException {
if (text == null) {
writeNull();
} else {
_append(JsonToken.VALUE_STRING, text);
}
}
@Override
public void writeString(char[] text, int offset, int len) throws IOException, JsonGenerationException {
writeString(new String(text, offset, len));
}
@Override
public void writeString(SerializableString text) throws IOException, JsonGenerationException {
if (text == null) {
writeNull();
} else {
_append(JsonToken.VALUE_STRING, text);
}
}
@Override
public void writeRawUTF8String(byte[] text, int offset, int length)
throws IOException, JsonGenerationException
{
// could add support for buffering if we really want it...
_reportUnsupportedOperation();
}
@Override
public void writeUTF8String(byte[] text, int offset, int length)
throws IOException, JsonGenerationException
{
// could add support for buffering if we really want it...
_reportUnsupportedOperation();
}
@Override
public void writeRaw(String text) throws IOException, JsonGenerationException {
_reportUnsupportedOperation();
}
@Override
public void writeRaw(String text, int offset, int len) throws IOException, JsonGenerationException {
_reportUnsupportedOperation();
}
@Override
public void writeRaw(SerializableString text) throws IOException, JsonGenerationException {
_reportUnsupportedOperation();
}
@Override
public void writeRaw(char[] text, int offset, int len) throws IOException, JsonGenerationException {
_reportUnsupportedOperation();
}
@Override
public void writeRaw(char c) throws IOException, JsonGenerationException {
_reportUnsupportedOperation();
}
@Override
public void writeRawValue(String text) throws IOException, JsonGenerationException {
_reportUnsupportedOperation();
}
@Override
public void writeRawValue(String text, int offset, int len) throws IOException, JsonGenerationException {
_reportUnsupportedOperation();
}
@Override
public void writeRawValue(char[] text, int offset, int len) throws IOException, JsonGenerationException {
_reportUnsupportedOperation();
}
/*
/**********************************************************
/* JsonGenerator implementation: write methods, primitive types
/**********************************************************
*/
@Override
public void writeNumber(short i) throws IOException, JsonGenerationException {
_append(JsonToken.VALUE_NUMBER_INT, Short.valueOf(i));
}
@Override
public void writeNumber(int i) throws IOException, JsonGenerationException {
_append(JsonToken.VALUE_NUMBER_INT, Integer.valueOf(i));
}
@Override
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> public void writeNumber(long l) throws IOException, JsonGenerationException {
_append(JsonToken.VALUE_NUMBER_INT, Long.valueOf(l));
}
@Override
public void writeNumber(double d) throws IOException,JsonGenerationException {
_append(JsonToken.VALUE_NUMBER_FLOAT, Double.valueOf(d));
}
@Override
public void writeNumber(float f) throws IOException, JsonGenerationException {
_append(JsonToken.VALUE_NUMBER_FLOAT, Float.valueOf(f));
}
@Override
public void writeNumber(BigDecimal dec) throws IOException,JsonGenerationException {
if (dec == null) {
writeNull();
} else {
_append(JsonToken.VALUE_NUMBER_FLOAT, dec);
}
}
@Override
public void writeNumber(BigInteger v) throws IOException, JsonGenerationException {
if (v == null) {
writeNull();
} else {
_append(JsonToken.VALUE_NUMBER_INT, v);
}
}
@Override
public void writeNumber(String encodedValue) throws IOException, JsonGenerationException {
/* 03-Dec-2010, tatu: related to [JACKSON-423], should try to keep as numeric
* identity as long as possible
*/
_append(JsonToken.VALUE_NUMBER_FLOAT, encodedValue);
}
@Override
public void writeBoolean(boolean state) throws IOException,JsonGenerationException {
_append(state ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE);
}
@Override
public void writeNull() throws IOException, JsonGenerationException {
_append(JsonToken.VALUE_NULL);
}
/*
/***********************************************************
/* JsonGenerator implementation: write methods for POJOs/trees
/***********************************************************
*/
@Override
public void writeObject(Object value) throws IOException
{
if (value == null) {
writeNull();
return;
}
Class<?> raw = value.getClass();
if (raw == byte[].class) {
_append(JsonToken.VALUE_EMBEDDED_OBJECT, value);
return;
} else if (_objectCodec == null) {
/* 28-May-2014, tatu: Tricky choice here; if no codec, should we
* err out, or just embed? For now, do latter.
*/
// throw new JsonMappingException("No ObjectCodec configured for TokenBuffer, writeObject() called");
_append(JsonToken.VALUE_EMBEDDED_OBJECT, value);
} else {
_objectCodec.writeValue(this, value);
}
}
@Override
public void writeTree(TreeNode node) throws IOException
{
if (node == null) {
writeNull();
return;
}
if (_objectCodec == null) {
// as with 'writeObject()', is codec optional?
_append(JsonToken.VALUE_EMBEDDED_OBJECT, node);
} else {
_objectCodec.writeTree(this, node);
}
}
/*
/***********************************************************
/* JsonGenerator implementation; binary
/***********************************************************
*/
@Override
public void writeBinary(Base64Variant b64variant, byte[] data, int offset, int len)
throws IOException, JsonGenerationException
{
/*
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>31-Dec-2009, tatu: can do this using multiple alternatives; but for
* now, let's try to limit number of conversions.
* The only (?) tricky thing is that of whether to preserve variant,
* seems pointless, so let's not worry about it unless there's some
* compelling reason to.
*/
byte[] copy = new byte[len];
System.arraycopy(data, offset, copy, 0, len);
writeObject(copy);
}
/**
* Although we could support this method, it does not necessarily make
* sense: we can not make good use of streaming because buffer must
* hold all the data. Because of this, currently this will simply
* throw {@link UnsupportedOperationException}
*/
@Override
public int writeBinary(Base64Variant b64variant, InputStream data, int dataLength) {
throw new UnsupportedOperationException();
}
/*
/***********************************************************
/* JsonGenerator implementation: native ids
/***********************************************************
*/
@Override
public boolean canWriteTypeId() {
return _hasNativeTypeIds;
}
@Override
public boolean canWriteObjectId() {
return _hasNativeObjectIds;
}
@Override
public void writeTypeId(Object id) {
_typeId = id;
_hasNativeId = true;
}
@Override
public void writeObjectId(Object id) {
_objectId = id;
_hasNativeId = true;
}
/*
/**********************************************************
/* JsonGenerator implementation; pass-through copy
/**********************************************************
*/
@Override
public void copyCurrentEvent(JsonParser jp) throws IOException, JsonProcessingException
{
if (_mayHaveNativeIds) {
_checkNativeIds(jp);
}
switch (jp.getCurrentToken()) {
case START_OBJECT:
writeStartObject();
break;
case END_OBJECT:
writeEndObject();
break;
case START_ARRAY:
writeStartArray();
break;
case END_ARRAY:
writeEndArray();
break;
case FIELD_NAME:
writeFieldName(jp.getCurrentName());
break;
case VALUE_STRING:
if (jp.hasTextCharacters()) {
writeString(jp.getTextCharacters(), jp.getTextOffset(), jp.getTextLength());
} else {
writeString(jp.getText());
}
break;
case VALUE_NUMBER_INT:
switch (jp.getNumberType()) {
case INT:
writeNumber(jp.getIntValue());
break;
case BIG_INTEGER:
writeNumber(jp.getBigIntegerValue());
break;
default:
writeNumber(jp.getLongValue());
}
break;
case VALUE_NUMBER_FLOAT:
switch (jp.getNumberType()) {
case BIG_DECIMAL:
writeNumber(jp.getDecimalValue());
break;
case FLOAT:
writeNumber(jp.getFloatValue());
break;
default:
writeNumber(jp.getDoubleValue());
}
break;
case VALUE_TRUE:
writeBoolean(true);
break;
case VALUE_FALSE:
writeBoolean(false);
break;
case VALUE_NULL:
writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
writeObject(jp.getEmbeddedObject());
break;
default:
throw new RuntimeException("Internal error
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>: should never end up through this code path");
}
}
@Override
public void copyCurrentStructure(JsonParser jp) throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
// Let's handle field-name separately first
if (t == JsonToken.FIELD_NAME) {
if (_mayHaveNativeIds) {
_checkNativeIds(jp);
}
writeFieldName(jp.getCurrentName());
t = jp.nextToken();
// fall-through to copy the associated value
}
if (_mayHaveNativeIds) {
_checkNativeIds(jp);
}
switch (t) {
case START_ARRAY:
writeStartArray();
while (jp.nextToken() != JsonToken.END_ARRAY) {
copyCurrentStructure(jp);
}
writeEndArray();
break;
case START_OBJECT:
writeStartObject();
while (jp.nextToken() != JsonToken.END_OBJECT) {
copyCurrentStructure(jp);
}
writeEndObject();
break;
default: // others are simple:
copyCurrentEvent(jp);
}
}
private final void _checkNativeIds(JsonParser jp) throws IOException, JsonProcessingException
{
if ((_typeId = jp.getTypeId()) != null) {
_hasNativeId = true;
}
if ((_objectId = jp.getObjectId()) != null) {
_hasNativeId = true;
}
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
protected final void _append(JsonToken type)
{
Segment next = _hasNativeId
? _last.append(_appendAt, type, _objectId, _typeId)
: _last.append(_appendAt, type);
if (next == null) {
++_appendAt;
} else {
_last = next;
_appendAt = 1; // since we added first at 0
}
}
protected final void _append(JsonToken type, Object value)
{
Segment next = _hasNativeId
? _last.append(_appendAt, type, value, _objectId, _typeId)
: _last.append(_appendAt, type, value);
if (next == null) {
++_appendAt;
} else {
_last = next;
_appendAt = 1;
}
}
protected final void _appendRaw(int rawType, Object value)
{
Segment next = _hasNativeId
? _last.appendRaw(_appendAt, rawType, value, _objectId, _typeId)
: _last.appendRaw(_appendAt, rawType, value);
if (next == null) {
++_appendAt;
} else {
_last = next;
_appendAt = 1;
}
}
@Override
protected void _reportUnsupportedOperation() {
throw new UnsupportedOperationException("Called operation not supported for TokenBuffer");
}
/*
/**********************************************************
/* Supporting classes
/**********************************************************
*/
protected final static class Parser
extends ParserMinimalBase
{
/*
/**********************************************************
/* Configuration
/**********************************************************
*/
protected ObjectCodec _codec;
/**
* @since 2.3
*/
protected final boolean _hasNativeTypeIds;
/**
* @since 2.
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>3
*/
protected final boolean _hasNativeObjectIds;
protected final boolean _hasNativeIds;
/*
/**********************************************************
/* Parsing state
/**********************************************************
*/
/**
* Currently active segment
*/
protected Segment _segment;
/**
* Pointer to current token within current segment
*/
protected int _segmentPtr;
/**
* Information about parser context, context in which
* the next token is to be parsed (root, array, object).
*/
protected JsonReadContext _parsingContext;
protected boolean _closed;
protected transient ByteArrayBuilder _byteBuilder;
protected JsonLocation _location = null;
/*
/**********************************************************
/* Construction, init
/**********************************************************
*/
@Deprecated // since 2.3
protected Parser(Segment firstSeg, ObjectCodec codec) {
this(firstSeg, codec, false, false);
}
/**
* @since 2.3
*/
public Parser(Segment firstSeg, ObjectCodec codec,
boolean hasNativeTypeIds,
boolean hasNativeObjectIds)
{
super(0);
_segment = firstSeg;
_segmentPtr = -1; // not yet read
_codec = codec;
_parsingContext = JsonReadContext.createRootContext(null);
_hasNativeTypeIds = hasNativeTypeIds;
_hasNativeObjectIds = hasNativeObjectIds;
_hasNativeIds = (hasNativeTypeIds | hasNativeObjectIds);
}
public void setLocation(JsonLocation l) {
_location = l;
}
@Override
public ObjectCodec getCodec() { return _codec; }
@Override
public void setCodec(ObjectCodec c) { _codec = c; }
@Override
public Version version() {
return com.fasterxml.jackson.databind.cfg.PackageVersion.VERSION;
}
/*
/**********************************************************
/* Extended API beyond JsonParser
/**********************************************************
*/
public JsonToken peekNextToken()
throws IOException, JsonParseException
{
// closed? nothing more to peek, either
if (_closed) return null;
Segment seg = _segment;
int ptr = _segmentPtr+1;
if (ptr >= Segment.TOKENS_PER_SEGMENT) {
ptr = 0;
seg = (seg == null) ? null : seg.next();
}
return (seg == null) ? null : seg.type(ptr);
}
/*
/**********************************************************
/* Closeable implementation
/**********************************************************
*/
@Override
public void close() throws IOException {
if (!_closed) {
_closed = true;
}
}
/*
/**********************************************************
/* Public API, traversal
/**********************************************************
*/
@Override
public JsonToken nextToken() throws IOException, JsonParseException
{
// If we are closed, nothing more to do
if (_closed || (_segment == null)) return null;
// Ok, then: any more tokens?
if (++_segmentPtr >= Segment.TOKENS_PER_SEGMENT) {
_segmentPtr = 0;
_segment = _segment.next();
if (_segment == null) {
return null;
}
}
_currToken = _segment.type(_segmentPtr);
// Field name? Need to update context
if (_currToken == JsonToken.FIELD_NAME) {
Object ob = _currentObject();
String name =
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> (ob instanceof String) ? ((String) ob) : ob.toString();
_parsingContext.setCurrentName(name);
} else if (_currToken == JsonToken.START_OBJECT) {
_parsingContext = _parsingContext.createChildObjectContext(-1, -1);
} else if (_currToken == JsonToken.START_ARRAY) {
_parsingContext = _parsingContext.createChildArrayContext(-1, -1);
} else if (_currToken == JsonToken.END_OBJECT
|| _currToken == JsonToken.END_ARRAY) {
// Closing JSON Object/Array? Close matching context
_parsingContext = _parsingContext.getParent();
// but allow unbalanced cases too (more close markers)
if (_parsingContext == null) {
_parsingContext = JsonReadContext.createRootContext(null);
}
}
return _currToken;
}
@Override
public boolean isClosed() { return _closed; }
/*
/**********************************************************
/* Public API, token accessors
/**********************************************************
*/
@Override
public JsonStreamContext getParsingContext() { return _parsingContext; }
@Override
public JsonLocation getTokenLocation() { return getCurrentLocation(); }
@Override
public JsonLocation getCurrentLocation() {
return (_location == null) ? JsonLocation.NA : _location;
}
@Override
public String getCurrentName() { return _parsingContext.getCurrentName(); }
@Override
public void overrideCurrentName(String name)
{
// Simple, but need to look for START_OBJECT/ARRAY's "off-by-one" thing:
JsonReadContext ctxt = _parsingContext;
if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) {
ctxt = ctxt.getParent();
}
try {
ctxt.setCurrentName(name);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/*
/**********************************************************
/* Public API, access to token information, text
/**********************************************************
*/
@Override
public String getText()
{
// common cases first:
if (_currToken == JsonToken.VALUE_STRING
|| _currToken == JsonToken.FIELD_NAME) {
Object ob = _currentObject();
if (ob instanceof String) {
return (String) ob;
}
return (ob == null) ? null : ob.toString();
}
if (_currToken == null) {
return null;
}
switch (_currToken) {
case VALUE_NUMBER_INT:
case VALUE_NUMBER_FLOAT:
Object ob = _currentObject();
return (ob == null) ? null : ob.toString();
default:
return _currToken.asString();
}
}
@Override
public char[] getTextCharacters() {
String str = getText();
return (str == null) ? null : str.toCharArray();
}
@Override
public int getTextLength() {
String str = getText();
return (str == null) ? 0 : str.length();
}
@Override
public int getTextOffset() { return 0; }
@Override
public boolean hasTextCharacters() {
// We never have raw buffer available, so:
return false;
}
/*
/**********************************************************
/* Public API, access to token information, numeric
/**********************************************************
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
*/
@Override
public BigInteger getBigIntegerValue() throws IOException, JsonParseException
{
Number n = getNumberValue();
if (n instanceof BigInteger) {
return (BigInteger) n;
}
if (getNumberType() == NumberType.BIG_DECIMAL) {
return ((BigDecimal) n).toBigInteger();
}
// int/long is simple, but let's also just truncate float/double:
return BigInteger.valueOf(n.longValue());
}
@Override
public BigDecimal getDecimalValue() throws IOException, JsonParseException
{
Number n = getNumberValue();
if (n instanceof BigDecimal) {
return (BigDecimal) n;
}
switch (getNumberType()) {
case INT:
case LONG:
return BigDecimal.valueOf(n.longValue());
case BIG_INTEGER:
return new BigDecimal((BigInteger) n);
default:
}
// float or double
return BigDecimal.valueOf(n.doubleValue());
}
@Override
public double getDoubleValue() throws IOException, JsonParseException {
return getNumberValue().doubleValue();
}
@Override
public float getFloatValue() throws IOException, JsonParseException {
return getNumberValue().floatValue();
}
@Override
public int getIntValue() throws IOException, JsonParseException
{
// optimize common case:
if (_currToken == JsonToken.VALUE_NUMBER_INT) {
return ((Number) _currentObject()).intValue();
}
return getNumberValue().intValue();
}
@Override
public long getLongValue() throws IOException, JsonParseException {
return getNumberValue().longValue();
}
@Override
public NumberType getNumberType() throws IOException, JsonParseException
{
Number n = getNumberValue();
if (n instanceof Integer) return NumberType.INT;
if (n instanceof Long) return NumberType.LONG;
if (n instanceof Double) return NumberType.DOUBLE;
if (n instanceof BigDecimal) return NumberType.BIG_DECIMAL;
if (n instanceof BigInteger) return NumberType.BIG_INTEGER;
if (n instanceof Float) return NumberType.FLOAT;
if (n instanceof Short) return NumberType.INT; // should be SHORT
return null;
}
@Override
public final Number getNumberValue() throws IOException, JsonParseException {
_checkIsNumber();
Object value = _currentObject();
if (value instanceof Number) {
return (Number) value;
}
// Difficult to really support numbers-as-Strings; but let's try.
// NOTE: no access to DeserializationConfig, unfortunately, so can not
// try to determine Double/BigDecimal preference...
if (value instanceof String) {
String str = (String) value;
if (str.indexOf('.') >= 0) {
return Double.parseDouble(str);
}
return Long.parseLong(str);
}
if (value == null) {
return null;
}
throw new IllegalStateException("Internal error: entry should be a Number, but is of type "
+value.getClass().getName());
}
/*
/**********************************************************
/* Public API, access to token information, other
/**********************************************************
*/
@Override
public Object getEmbeddedObject()
{
if (_currToken == JsonToken.VALUE_EMBEDDED_OBJECT) {
return _currentObject();
}
return null;
}
@Override
@SuppressWarnings
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>("resource")
public byte[] getBinaryValue(Base64Variant b64variant) throws IOException, JsonParseException
{
// First: maybe we some special types?
if (_currToken == JsonToken.VALUE_EMBEDDED_OBJECT) {
// Embedded byte array would work nicely...
Object ob = _currentObject();
if (ob instanceof byte[]) {
return (byte[]) ob;
}
// fall through to error case
}
if (_currToken != JsonToken.VALUE_STRING) {
throw _constructError("Current token ("+_currToken+") not VALUE_STRING (or VALUE_EMBEDDED_OBJECT with byte[]), can not access as binary");
}
final String str = getText();
if (str == null) {
return null;
}
ByteArrayBuilder builder = _byteBuilder;
if (builder == null) {
_byteBuilder = builder = new ByteArrayBuilder(100);
} else {
_byteBuilder.reset();
}
_decodeBase64(str, builder, b64variant);
return builder.toByteArray();
}
@Override
public int readBinaryValue(Base64Variant b64variant, OutputStream out)
throws IOException, JsonParseException
{
byte[] data = getBinaryValue(b64variant);
if (data != null) {
out.write(data, 0, data.length);
return data.length;
}
return 0;
}
/*
/**********************************************************
/* Public API, native ids
/**********************************************************
*/
@Override
public boolean canReadObjectId() {
return _hasNativeObjectIds;
}
@Override
public boolean canReadTypeId() {
return _hasNativeTypeIds;
}
@Override
public Object getTypeId() {
return _segment.findTypeId(_segmentPtr);
}
@Override
public Object getObjectId() {
return _segment.findObjectId(_segmentPtr);
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
protected final Object _currentObject() {
return _segment.get(_segmentPtr);
}
protected final void _checkIsNumber() throws JsonParseException
{
if (_currToken == null || !_currToken.isNumeric()) {
throw _constructError("Current token ("+_currToken+") not numeric, can not use numeric value accessors");
}
}
@Override
protected void _handleEOF() throws JsonParseException {
_throwInternal();
}
}
/**
* Individual segment of TokenBuffer that can store up to 16 tokens
* (limited by 4 bits per token type marker requirement).
* Current implementation uses fixed length array; could alternatively
* use 16 distinct fields and switch statement (slightly more efficient
* storage, slightly slower access)
*/
protected final static class Segment
{
public final static int TOKENS_PER_SEGMENT = 16;
/**
* Static array used for fast conversion between token markers and
* matching {@link JsonToken} instances
*/
private final static JsonToken[] TOKEN_TYPES_BY_INDEX;
static {
// ... here we know that there are <= 15 values in JsonToken enum
TOKEN_TYPES_BY_INDEX = new JsonToken[16];
JsonToken[] t = JsonToken.values();
// and reserve entry 0
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> for "not available"
System.arraycopy(t, 1, TOKEN_TYPES_BY_INDEX, 1, Math.min(15, t.length - 1));
}
// // // Linking
protected Segment _next;
// // // State
/**
* Bit field used to store types of buffered tokens; 4 bits per token.
* Value 0 is reserved for "not in use"
*/
protected long _tokenTypes;
// Actual tokens
protected final Object[] _tokens = new Object[TOKENS_PER_SEGMENT];
/**
* Lazily constructed Map for storing native type and object ids, if any
*/
protected TreeMap<Integer,Object> _nativeIds;
public Segment() { }
// // // Accessors
public JsonToken type(int index)
{
long l = _tokenTypes;
if (index > 0) {
l >>= (index << 2);
}
int ix = ((int) l) & 0xF;
return TOKEN_TYPES_BY_INDEX[ix];
}
public int rawType(int index)
{
long l = _tokenTypes;
if (index > 0) {
l >>= (index << 2);
}
int ix = ((int) l) & 0xF;
return ix;
}
public Object get(int index) {
return _tokens[index];
}
public Segment next() { return _next; }
/**
* Accessor for checking whether this segment may have native
* type or object ids.
*/
public boolean hasIds() {
return _nativeIds != null;
}
// // // Mutators
public Segment append(int index, JsonToken tokenType)
{
if (index < TOKENS_PER_SEGMENT) {
set(index, tokenType);
return null;
}
_next = new Segment();
_next.set(0, tokenType);
return _next;
}
public Segment append(int index, JsonToken tokenType,
Object objectId, Object typeId)
{
if (index < TOKENS_PER_SEGMENT) {
set(index, tokenType, objectId, typeId);
return null;
}
_next = new Segment();
_next.set(0, tokenType, objectId, typeId);
return _next;
}
public Segment append(int index, JsonToken tokenType, Object value)
{
if (index < TOKENS_PER_SEGMENT) {
set(index, tokenType, value);
return null;
}
_next = new Segment();
_next.set(0, tokenType, value);
return _next;
}
public Segment append(int index, JsonToken tokenType, Object value,
Object objectId, Object typeId)
{
if (index < TOKENS_PER_SEGMENT) {
set(index, tokenType, value, objectId, typeId);
return null;
}
_next = new Segment();
_next.set(0, tokenType, value, objectId, typeId);
return _next;
}
public Segment appendRaw(int index, int rawTokenType, Object value)
{
if (index < TOKENS_PER_SEGMENT) {
set(index, rawTokenType, value);
return null
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>;
}
_next = new Segment();
_next.set(0, rawTokenType, value);
return _next;
}
public Segment appendRaw(int index, int rawTokenType, Object value,
Object objectId, Object typeId)
{
if (index < TOKENS_PER_SEGMENT) {
set(index, rawTokenType, value, objectId, typeId);
return null;
}
_next = new Segment();
_next.set(0, rawTokenType, value, objectId, typeId);
return _next;
}
private void set(int index, JsonToken tokenType)
{
/* Assumption here is that there are no overwrites, just appends;
* and so no masking is needed (nor explicit setting of null)
*/
long typeCode = tokenType.ordinal();
if (index > 0) {
typeCode <<= (index << 2);
}
_tokenTypes |= typeCode;
}
private void set(int index, JsonToken tokenType,
Object objectId, Object typeId)
{
long typeCode = tokenType.ordinal();
if (index > 0) {
typeCode <<= (index << 2);
}
_tokenTypes |= typeCode;
assignNativeIds(index, objectId, typeId);
}
private void set(int index, JsonToken tokenType, Object value)
{
_tokens[index] = value;
long typeCode = tokenType.ordinal();
if (index > 0) {
typeCode <<= (index << 2);
}
_tokenTypes |= typeCode;
}
private void set(int index, JsonToken tokenType, Object value,
Object objectId, Object typeId)
{
_tokens[index] = value;
long typeCode = tokenType.ordinal();
if (index > 0) {
typeCode <<= (index << 2);
}
_tokenTypes |= typeCode;
assignNativeIds(index, objectId, typeId);
}
private void set(int index, int rawTokenType, Object value)
{
_tokens[index] = value;
long typeCode = (long) rawTokenType;
if (index > 0) {
typeCode <<= (index << 2);
}
_tokenTypes |= typeCode;
}
private void set(int index, int rawTokenType, Object value, Object objectId, Object typeId)
{
_tokens[index] = value;
long typeCode = (long) rawTokenType;
if (index > 0) {
typeCode <<= (index << 2);
}
_tokenTypes |= typeCode;
assignNativeIds(index, objectId, typeId);
}
private final void assignNativeIds(int index, Object objectId, Object typeId)
{
if (_nativeIds == null) {
_nativeIds = new TreeMap<Integer,Object>();
}
if (objectId != null) {
_nativeIds.put(_objectIdIndex(index), objectId);
}
if (typeId != null) {
_nativeIds.put(_typeIdIndex(index), typeId);
}
}
/**
* @since 2.3
*/
public Object findObjectId(int index) {
return (_nativeIds == null)
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
// Issue#381
if (jp.getCurrentToken() == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final T value = deserialize(jp, ctxt);
if (jp.nextToken() != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single '" + _valueClass.getName() + "' value but there was more than a single value in the array");
}
return value;
}
// 22-Sep-2012, tatu: For 2.1, use this new method, may force coercion:
String text = jp.getValueAsString();
if (text != null) { // has String representation
if (text.length() == 0 || (text = text.trim()).length() == 0) {
// 04-Feb-2013, tatu: Usually should become null; but not always
return _deserializeFromEmptyString();
}
Exception cause = null;
try {
T result = _deserialize(text, ctxt);
if (result != null) {
return result;
}
} catch (IllegalArgumentException iae) {
cause = iae;
}
String msg = "not a valid textual representation";
if (cause != null) {
String m2 = cause.getMessage();
if (m2 != null) {
msg = msg + ", problem: "+m2;
}
}
JsonMappingException e = ctxt.weirdStringException(text, _valueClass, msg);
if (cause != null) {
e.initCause(cause);
}
throw e;
// nothing to do here, yet? We'll fail anyway
}
if (jp.getCurrentToken() == JsonToken.VALUE_EMBEDDED_OBJECT) {
// Trivial cases; null to null, instance of type itself returned as is
Object ob = jp.getEmbeddedObject();
if (ob == null) {
return null;
}
if (_valueClass.isAssignableFrom(ob.getClass())) {
return (T) ob;
}
return _deserializeEmbedded(ob, ctxt);
}
throw ctxt.mappingException(_valueClass);
}
protected abstract T _deserialize(String value, DeserializationContext ctxt) throws IOException;
protected T _deserializeEmbedded(Object ob, DeserializationContext ctxt) throws IOException {
// default impl: error out
throw ctxt.mappingException("Don't know how to convert embedded Object of type "+ob.getClass().getName()+" into "+_valueClass.getName());
}
protected T _deserializeFromEmptyString() throws IOException {
return null;
}
/*
/**********************************************************
/* A general-purpose implementation
/**********************************************************
*/
/**
* "Chameleon" deserializer that works on simple types that are deserialized
* from a simple String.
*
* @since 2.4
*/
public static class Std extends FromStringDeserializer<Object>
{
private static final long serialVersionUID = 1;
public final static int STD_FILE = 1;
public final static int STD_URL = 2;
public final static int
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.lang.reflect.Method;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.EnumResolver;
/**
* Deserializer class that can deserialize instances of
* specified Enum class from Strings and Integers.
*/
public class EnumDeserializer
extends StdScalarDeserializer<Enum<?>>
{
private static final long serialVersionUID = -5893263645879532318L;
protected final EnumResolver<?> _resolver;
public EnumDeserializer(EnumResolver<?> res)
{
super(Enum.class);
_resolver = res;
}
/**
* Factory method used when Enum instances are to be deserialized
* using a creator (static factory method)
*
* @return Deserializer based on given factory method, if type was suitable;
* null if type can not be used
*/
public static JsonDeserializer<?> deserializerForCreator(DeserializationConfig config,
Class<?> enumClass, AnnotatedMethod factory)
{
// note: caller has verified there's just one arg; but we must verify its type
Class<?> paramClass = factory.getRawParameterType(0);
if (paramClass == String.class) {
paramClass = null;
} else if (paramClass == Integer.TYPE || paramClass == Integer.class) {
paramClass = Integer.class;
} else if (paramClass == Long.TYPE || paramClass == Long.class) {
paramClass = Long.class;
} else {
throw new IllegalArgumentException("Parameter #0 type for factory method ("+factory
+") not suitable, must be java.lang.String or int/Integer/long/Long");
}
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(factory.getMember());
}
return new FactoryBasedDeserializer(enumClass, factory, paramClass);
}
/*
/**********************************************************
/* Default JsonDeserializer implementation
/**********************************************************
*/
/**
* Because of costs associated with constructing Enum resolvers,
* let's cache instances by default.
*/
@Override
public boolean isCachable() { return true; }
@Override
public Enum<?> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
JsonToken curr = jp.getCurrentToken();
// Usually should just get string value:
if (curr == JsonToken.VALUE_STRING || curr == JsonToken.FIELD_NAME) {
String name = jp.getText();
Enum<?> result = _resolver.findEnum(name);
if (result == null) {
return _deserializeAltString(jp, ctxt, name);
}
return result;
}
// But let's consider int acceptable as well (if within ordinal range)
if (curr == JsonToken.VALUE_NUMBER_INT) {
// ... unless told not to do that. :-) (as per [JACKSON-412]
if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS)) {
throw ctxt.mappingException("
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>Not allowed to deserialize Enum value out of JSON number (disable DeserializationConfig.DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS to allow)");
}
int index = jp.getIntValue();
Enum<?> result = _resolver.getEnum(index);
if (result == null && !ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) {
throw ctxt.weirdNumberException(Integer.valueOf(index), _resolver.getEnumClass(),
"index value outside legal index range [0.."+_resolver.lastValidIndex()+"]");
}
return result;
}
return _deserializeOther(jp, ctxt);
}
private final Enum<?> _deserializeAltString(JsonParser jp, DeserializationContext ctxt,
String name) throws IOException
{
name = name.trim();
if (name.length() == 0) {
if (ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) {
return null;
}
} else {
// [#149]: Allow use of 'String' indexes as well
char c = name.charAt(0);
if (c >= '0' && c <= '9') {
try {
int ix = Integer.parseInt(name);
Enum<?> result = _resolver.getEnum(ix);
if (result != null) {
return result;
}
} catch (NumberFormatException e) {
// fine, ignore, was not an integer
}
}
}
if (!ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) {
throw ctxt.weirdStringException(name, _resolver.getEnumClass(),
"value not one of declared Enum instance names: "+_resolver.getEnums());
}
return null;
}
private final Enum<?> _deserializeOther(JsonParser jp, DeserializationContext ctxt) throws IOException
{
JsonToken curr = jp.getCurrentToken();
// Issue#381
if (curr == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final Enum<?> parsed = deserialize(jp, ctxt);
curr = jp.nextToken();
if (curr != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single '" + _resolver.getEnumClass().getName() + "' value but there was more than a single value in the array");
}
return parsed;
}
throw ctxt.mappingException(_resolver.getEnumClass());
}
/*
/**********************************************************
/* Additional helper classes
/**********************************************************
*/
/**
* Deserializer that uses a single-String static factory method
* for locating Enum values by String id.
*/
protected static class FactoryBasedDeserializer
extends StdScalarDeserializer<Object>
{
private static final long serialVersionUID = -7775129435872564122L;
protected final Class<?> _enumClass;
// Marker type; null if String expected; otherwise numeric wrapper
protected final Class<?> _inputType;
protected final Method _factory;
public FactoryBasedDeserializer(Class<?> cls, AnnotatedMethod f,
Class<?> inputType)
{
super
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>(Enum.class);
_enumClass = cls;
_factory = f.getAnnotated();
_inputType = inputType;
}
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// couple of accepted types...
Object value;
if (_inputType == null) {
value = jp.getText();
} else if (_inputType == Integer.class) {
value = Integer.valueOf(jp.getValueAsInt());
} else if (_inputType == Long.class) {
value = Long.valueOf(jp.getValueAsLong());
} else {
throw ctxt.mappingException(_enumClass);
}
try {
return _factory.invoke(_enumClass, value);
} catch (Exception e) {
Throwable t = ClassUtil.getRootCause(e);
if (t instanceof IOException) {
throw (IOException) t;
}
throw ctxt.instantiationException(_enumClass, t);
}
}
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
/**
* Intermediate base class for serializers used for serializing
* types that contain element(s) of other types, such as arrays,
* {@link java.util.Collection}s (<code>Lists</code>, <code>Sets</code>
* etc) and {@link java.util.Map}s and iterable things
* ({@link java.util.Iterator}s).
*/
public abstract class ContainerSerializer<T>
extends StdSerializer<T>
{
/*
/**********************************************************
/* Construction, initialization
/**********************************************************
*/
protected ContainerSerializer(Class<T> t) {
super(t);
}
/**
* Alternate constructor that is (alas!) needed to work
* around kinks of generic type handling
*
* @param t
*/
protected ContainerSerializer(Class<?> t, boolean dummy) {
super(t, dummy);
}
protected ContainerSerializer(ContainerSerializer<?> src) {
super(src._handledType, false);
}
/**
* Factory(-like) method that can be used to construct a new container
* serializer that uses specified {@link TypeSerializer} for decorating
* contained values with additional type information.
*
* @param vts Type serializer to use for contained values; can be null,
* in which case 'this' serializer is returned as is
* @return Serializer instance that uses given type serializer for values if
* that is possible (or if not, just 'this' serializer)
*/
public ContainerSerializer<?> withValueTypeSerializer(TypeSerializer vts) {
if (vts == null) return this;
return _withValueTypeSerializer(vts);
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
/**
* Accessor for finding declared (static) element type for
* type this serializer is used for.
*/
public abstract JavaType getContentType();
/**
* Accessor for serializer used for serializing contents
* (List and array elements, Map values etc) of the
* container for which this serializer is used, if it is
* known statically.
* Note that for dynamic types this may return null; if so,
* caller has to instead use {@link #getContentType()} and
* {@link com.fasterxml.jackson.databind.SerializerProvider#findValueSerializer}.
*/
public abstract JsonSerializer<?> getContentSerializer();
/*
/**********************************************************
/* Abstract methods for sub-classes to implement
/**********************************************************
*/
/* Overridden as abstract, to force re-implementation; necessary for all
* collection types.
*/
@Override
public abstract boolean isEmpty(T value);
/**
* Method called to determine if the given value (of type handled by
* this serializer) contains exactly one element.
*<p>
* Note: although it might seem sensible to instead define something
* like "getElementCount()" method, this would not work well for
* containers that do not keep track of size (like linked lists may
* not).
*/
public abstract boolean hasSingleElement(T value);
/**
* Method that needs to be implemented to
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.type;
import java.util.*;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.util.ClassUtil;
/**
* Simple recursive-descent parser for parsing canonical {@link JavaType}
* representations and constructing type instances.
*
* @author tatu
*/
public class TypeParser
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
protected final TypeFactory _factory;
public TypeParser(TypeFactory f) {
_factory = f;
}
public JavaType parse(String canonical)
throws IllegalArgumentException
{
canonical = canonical.trim();
MyTokenizer tokens = new MyTokenizer(canonical);
JavaType type = parseType(tokens);
// must be end, now
if (tokens.hasMoreTokens()) {
throw _problem(tokens, "Unexpected tokens after complete type");
}
return type;
}
protected JavaType parseType(MyTokenizer tokens)
throws IllegalArgumentException
{
if (!tokens.hasMoreTokens()) {
throw _problem(tokens, "Unexpected end-of-string");
}
Class<?> base = findClass(tokens.nextToken(), tokens);
// either end (ok, non generic type), or generics
if (tokens.hasMoreTokens()) {
String token = tokens.nextToken();
if ("<".equals(token)) {
return _factory._fromParameterizedClass(base, parseTypes(tokens));
}
// can be comma that separates types, or closing '>'
tokens.pushBack(token);
}
return _factory._fromClass(base, null);
}
protected List<JavaType> parseTypes(MyTokenizer tokens)
throws IllegalArgumentException
{
ArrayList<JavaType> types = new ArrayList<JavaType>();
while (tokens.hasMoreTokens()) {
types.add(parseType(tokens));
if (!tokens.hasMoreTokens()) break;
String token = tokens.nextToken();
if (">".equals(token)) return types;
if (!",".equals(token)) {
throw _problem(tokens, "Unexpected token '"+token+"', expected ',' or '>')");
}
}
throw _problem(tokens, "Unexpected end-of-string");
}
protected Class<?> findClass(String className, MyTokenizer tokens)
{
try {
return ClassUtil.findClass(className);
} catch (Exception e) {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
throw _problem(tokens, "Can not locate class '"+className+"', problem: "+e.getMessage());
}
}
protected IllegalArgumentException _problem(MyTokenizer tokens, String msg)
{
return new IllegalArgumentException("Failed to parse type '"+tokens.getAllInput()
+"' (remaining: '"+tokens.getRemainingInput()+"'): "+msg);
}
final static class MyTokenizer
extends StringTokenizer
{
protected final String _input;
protected int _index;
protected String _pushbackToken;
public MyTokenizer(String str) {
super(str, "<,>", true);
_input = str;
}
@Override
public boolean hasMoreTokens() {
return (_pushbackToken != null) || super.hasMoreTokens();
}
@Override
public String nextToken() {
String token;
if (_
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>pushbackToken != null) {
token = _pushbackToken;
_pushbackToken = null;
} else {
token = super.nextToken();
}
_index += token.length();
return token;
}
public void pushBack(String token) {
_pushbackToken = token;
_index -= token.length();
}
public String getAllInput() { return _input; }
public String getUsedInput() { return _input.substring(0, _index); }
public String getRemainingInput() { return _input.substring(_index); }
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import com.fasterxml.jackson.annotation.ObjectIdGenerator.IdKey;
import com.fasterxml.jackson.annotation.SimpleObjectIdResolver;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId;
import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId.Referring;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.util.ClassUtil;
/**
* Complete {@link DeserializationContext} implementation that adds
* extended API for {@link ObjectMapper} (and {@link ObjectReader})
* to call, as well as implements certain parts that base class
* has left abstract.
* The remaining abstract methods ({@link #createInstance}, {@link #with})
* are left so that custom implementations will properly implement them
* to return intended subtype.
*/
public abstract class DefaultDeserializationContext
extends DeserializationContext
implements java.io.Serializable // since 2.1
{
private static final long serialVersionUID = 1L;
protected transient LinkedHashMap<ObjectIdGenerator.IdKey, ReadableObjectId> _objectIds;
private List<ObjectIdResolver> _objectIdResolvers;
/**
* Constructor that will pass specified deserializer factory and
* cache: cache may be null (in which case default implementation
* will be used), factory can not be null
*/
protected DefaultDeserializationContext(DeserializerFactory df, DeserializerCache cache) {
super(df, cache);
}
protected DefaultDeserializationContext(DefaultDeserializationContext src,
DeserializationConfig config, JsonParser jp, InjectableValues values) {
super(src, config, jp, values);
}
protected DefaultDeserializationContext(DefaultDeserializationContext src,
DeserializerFactory factory) {
super(src, factory);
}
/*
/**********************************************************
/* Abstract methods impls, Object Id
/**********************************************************
*/
@Override
public ReadableObjectId findObjectId(Object id, ObjectIdGenerator<?> gen, ObjectIdResolver resolverType)
{
final ObjectIdGenerator.IdKey key = gen.key(id);
if (_objectIds == null) {
_objectIds = new LinkedHashMap<ObjectIdGenerator.IdKey,ReadableObjectId>();
} else {
ReadableObjectId entry = _objectIds.get(key);
if (entry != null) {
return entry;
}
}
// Not seen yet, must create entry and configure resolver.
ObjectIdResolver resolver = null;
if (_objectIdResolvers == null) {
_objectIdResolvers = new ArrayList<ObjectIdResolver>(8);
} else {
for (ObjectIdResolver res : _objectIdResolvers) {
if (res.canUseFor(resolverType)) {
resolver = res;
break;
}
}
}
if (resolver == null) {
resolver = resolverType.newForDeserialization(this);
/* !!!
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> 18-Jun-2014, pgelinas: Temporary fix for [#490] until real
* fix (for jackson-annotations, SimpleObjectIdResolver) can be added.
*/
if (resolverType instanceof SimpleObjectIdResolver) {
resolver = new SimpleObjectIdResolver();
}
_objectIdResolvers.add(resolver);
}
ReadableObjectId entry = new ReadableObjectId(key);
entry.setResolver(resolver);
_objectIds.put(key, entry);
return entry;
}
@Deprecated // since 2.4
@Override
public ReadableObjectId findObjectId(Object id, ObjectIdGenerator<?> gen) {
return findObjectId(id, gen, new SimpleObjectIdResolver());
}
@Override
public void checkUnresolvedObjectId() throws UnresolvedForwardReference
{
if (_objectIds == null) {
return;
}
UnresolvedForwardReference exception = null;
for (Entry<IdKey,ReadableObjectId> entry : _objectIds.entrySet()) {
ReadableObjectId roid = entry.getValue();
if (roid.hasReferringProperties()) {
if (exception == null) {
exception = new UnresolvedForwardReference("Unresolved forward references for: ");
}
for (Iterator<Referring> iterator = roid.referringProperties(); iterator.hasNext();) {
Referring referring = iterator.next();
exception.addUnresolvedId(roid.getKey().key, referring.getBeanType(), referring.getLocation());
}
}
}
if (exception != null) {
throw exception;
}
}
/*
/**********************************************************
/* Abstract methods impls, other factory methods
/**********************************************************
*/
@SuppressWarnings("unchecked")
@Override
public JsonDeserializer<Object> deserializerInstance(Annotated ann, Object deserDef)
throws JsonMappingException
{
if (deserDef == null) {
return null;
}
JsonDeserializer<?> deser;
if (deserDef instanceof JsonDeserializer) {
deser = (JsonDeserializer<?>) deserDef;
} else {
/* Alas, there's no way to force return type of "either class
* X or Y" -- need to throw an exception after the fact
*/
if (!(deserDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned deserializer definition of type "+deserDef.getClass().getName()+"; expected type JsonDeserializer or Class<JsonDeserializer> instead");
}
Class<?> deserClass = (Class<?>)deserDef;
// there are some known "no class" markers to consider too:
if (deserClass == JsonDeserializer.None.class || ClassUtil.isBogusClass(deserClass)) {
return null;
}
if (!JsonDeserializer.class.isAssignableFrom(deserClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "+deserClass.getName()+"; expected Class<JsonDeserializer>");
}
HandlerInstantiator hi = _config.getHandlerInstantiator();
deser = (hi == null) ? null : hi.deserializerInstance(_config, ann, deserClass);
if (deser == null) {
deser = (JsonDeserializer<?>) ClassUtil.createInstance(deserClass,
_config.canOverrideAccessModifiers());
}
}
// First: need to resolve
if (deser instanceof ResolvableDeserializer) {
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
Class<?> type = _anySetterMethod.getRawParameterType(0);
if (type != String.class && type != Object.class) {
throw new IllegalArgumentException("Invalid 'any-setter' annotation on method "+_anySetterMethod.getName()+"(): first argument not of type String or Object, but "+type.getName());
}
}
return _anySetterMethod;
}
@Override
public Map<Object, AnnotatedMember> findInjectables() {
return _injectables;
}
@Override
public List<AnnotatedConstructor> getConstructors() {
return _classInfo.getConstructors();
}
@Override
public Object instantiateBean(boolean fixAccess)
{
AnnotatedConstructor ac = _classInfo.getDefaultConstructor();
if (ac == null) {
return null;
}
if (fixAccess) {
ac.fixAccess();
}
try {
return ac.getAnnotated().newInstance();
} catch (Exception e) {
Throwable t = e;
while (t.getCause() != null) {
t = t.getCause();
}
if (t instanceof Error) throw (Error) t;
if (t instanceof RuntimeException) throw (RuntimeException) t;
throw new IllegalArgumentException("Failed to instantiate bean of type "+_classInfo.getAnnotated().getName()+": ("+t.getClass().getName()+") "+t.getMessage(), t);
}
}
/*
/**********************************************************
/* Simple accessors, extended
/**********************************************************
*/
@Override
public AnnotatedMethod findMethod(String name, Class<?>[] paramTypes) {
return _classInfo.findMethod(name, paramTypes);
}
/*
/**********************************************************
/* General per-class annotation introspection
/**********************************************************
*/
@Override
public JsonFormat.Value findExpectedFormat(JsonFormat.Value defValue)
{
if (_annotationIntrospector != null) {
JsonFormat.Value v = _annotationIntrospector.findFormat(_classInfo);
if (v != null) {
return v;
}
}
return defValue;
}
/*
/**********************************************************
/* Introspection for serialization
/**********************************************************
*/
@Override
public Converter<Object,Object> findSerializationConverter()
{
if (_annotationIntrospector == null) {
return null;
}
return _createConverter(_annotationIntrospector.findSerializationConverter(_classInfo));
}
/**
* Method for determining whether null properties should be written
* out for a Bean of introspected type. This is based on global
* feature (lowest priority, passed as argument)
* and per-class annotation (highest priority).
*/
@Override
public JsonInclude.Include findSerializationInclusion(JsonInclude.Include defValue)
{
if (_annotationIntrospector == null) {
return defValue;
}
return _annotationIntrospector.findSerializationInclusion(_classInfo, defValue);
}
/**
* Method used to locate the method of introspected class that
* implements {@link com.fasterxml.jackson.annotation.JsonAnyGetter}.
* If no such method exists null is returned.
* If more than one are found, an exception is thrown.
*/
@Override
public AnnotatedMember findAnyGetter() throws IllegalArgumentException
{
if (_anyGetter != null) {
/* For now let's
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import java.util.List;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
/**
* This intermediate base class is used for all leaf nodes, that is,
* all non-container (array or object) nodes, except for the
* "missing node".
*/
public abstract class ValueNode
extends BaseJsonNode
{
protected ValueNode() { }
@Override
protected JsonNode _at(JsonPointer ptr) {
// will only allow direct matches, but no traversal through
// (base class checks for direct match)
return MissingNode.getInstance();
}
/**
* All current value nodes are immutable, so we can just return
* them as is.
*/
@SuppressWarnings("unchecked")
@Override
public <T extends JsonNode> T deepCopy() { return (T) this; }
@Override public abstract JsonToken asToken();
@Override
public void serializeWithType(JsonGenerator jg, SerializerProvider provider,
TypeSerializer typeSer)
throws IOException, JsonProcessingException
{
typeSer.writeTypePrefixForScalar(this, jg);
serialize(jg, provider);
typeSer.writeTypeSuffixForScalar(this, jg);
}
/*
/**********************************************************************
/* Base impls for standard methods
/**********************************************************************
*/
@Override
public String toString() { return asText(); }
/*
**********************************************************************
* Navigation methods
**********************************************************************
*/
@Override
public final JsonNode get(int index) { return null; }
@Override
public final JsonNode path(int index) { return MissingNode.getInstance(); }
@Override
public final boolean has(int index) { return false; }
@Override
public final boolean hasNonNull(int index) { return false; }
@Override
public final JsonNode get(String fieldName) { return null; }
@Override
public final JsonNode path(String fieldName) { return MissingNode.getInstance(); }
@Override
public final boolean has(String fieldName) { return false; }
@Override
public final boolean hasNonNull(String fieldName) { return false; }
/*
**********************************************************************
* Find methods: all "leaf" nodes return the same for these
**********************************************************************
*/
@Override
public final JsonNode findValue(String fieldName) {
return null;
}
// note: co-variant return type
@Override
public final ObjectNode findParent(String fieldName) {
return null;
}
@Override
public final List<JsonNode> findValues(String fieldName, List<JsonNode> foundSoFar) {
return foundSoFar;
}
@Override
public final List<String> findValuesAsText(String fieldName, List<String> foundSoFar) {
return foundSoFar;
}
@Override
public final List<JsonNode> findParents(String fieldName, List<JsonNode> foundSoFar) {
return foundSoFar;
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>, on
* specified Object, and return whatever delegating accessor
* returned (if anything)
*<p>
* Note: this is an optional operation, not supported by all
* implementations, creator-backed properties for example do not
* support this method.
*
* @since 2.0
*/
public abstract Object setAndReturn(Object instance, Object value)
throws IOException;
/**
* This method is needed by some specialized bean deserializers,
* and also called by some {@link #deserializeAndSet} implementations.
*<p>
* Pre-condition is that passed parser must point to the first token
* that should be consumed to produce the value (the only value for
* scalars, multiple for Objects and Arrays).
*<p>
* Note that this method is final for performance reasons: to override
* functionality you must override other methods that call this method;
* this method should also not be called directly unless you really know
* what you are doing (and probably not even then).
*/
public final Object deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NULL) {
return (_nullProvider == null) ? null : _nullProvider.nullValue(ctxt);
}
if (_valueTypeDeserializer != null) {
return _valueDeserializer.deserializeWithType(jp, ctxt, _valueTypeDeserializer);
}
return _valueDeserializer.deserialize(jp, ctxt);
}
/*
/**********************************************************
/* Helper methods
/**********************************************************
*/
/**
* Method that takes in exception of any type, and casts or wraps it
* to an IOException or its subclass.
*/
protected void _throwAsIOE(Exception e, Object value)
throws IOException
{
if (e instanceof IllegalArgumentException) {
String actType = (value == null) ? "[NULL]" : value.getClass().getName();
StringBuilder msg = new StringBuilder("Problem deserializing property '").append(getName());
msg.append("' (expected type: ").append(getType());
msg.append("; actual type: ").append(actType).append(")");
String origMsg = e.getMessage();
if (origMsg != null) {
msg.append(", problem: ").append(origMsg);
} else {
msg.append(" (no error message provided)");
}
throw new JsonMappingException(msg.toString(), null, e);
}
_throwAsIOE(e);
}
protected IOException _throwAsIOE(Exception e)
throws IOException
{
if (e instanceof IOException) {
throw (IOException) e;
}
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
// let's wrap the innermost problem
Throwable th = e;
while (th.getCause() != null) {
th = th.getCause();
}
throw new JsonMappingException(th.getMessage(), null, th);
}
@Override public String toString() { return "[property '"+getName()+"']"; }
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>td = _valueTypeDeserializer;
if (vtd != null) {
vtd = vtd.forProperty(property);
}
return withResolved(kd, vd, vtd);
}
/**
* Because of costs associated with constructing Enum resolvers,
* let's cache instances by default.
*/
@Override
public boolean isCachable() { return true; }
/*
/**********************************************************
/* Actual deserialization
/**********************************************************
*/
@Override
public EnumMap<?,?> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException
{
// Ok: must point to START_OBJECT
if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
throw ctxt.mappingException(EnumMap.class);
}
EnumMap result = constructMap();
final JsonDeserializer<Object> valueDes = _valueDeserializer;
final TypeDeserializer typeDeser = _valueTypeDeserializer;
while ((jp.nextToken()) != JsonToken.END_OBJECT) {
Enum<?> key = _keyDeserializer.deserialize(jp, ctxt);
if (key == null) {
if (!ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) {
String value = null;
try { // bit ugly, but will have to do; works with usual scalars
if (jp.hasCurrentToken()) {
value = jp.getText();
}
} catch (Exception e) { }
throw ctxt.weirdStringException(value, _enumClass, "value not one of declared Enum instance names");
}
/* 24-Mar-2012, tatu: Null won't work as a key anyway, so let's
* just skip the entry then. But we must skip the value then.
*/
jp.nextToken();
jp.skipChildren();
continue;
}
// And then the value...
JsonToken t = jp.nextToken();
/* note: MUST check for nulls separately: deserializers will
* not handle them (and maybe fail or return bogus data)
*/
Object value;
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue();
} else if (typeDeser == null) {
value = valueDes.deserialize(jp, ctxt);
} else {
value = valueDes.deserializeWithType(jp, ctxt, typeDeser);
}
result.put(key, value);
}
return result;
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
// In future could check current token... for now this should be enough:
return typeDeserializer.deserializeTypedFromObject(jp, ctxt);
}
private EnumMap<?,?> constructMap() {
return new EnumMap(_enumClass);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
/**********************************************************
*/
public static Class<?> findClass(String className) throws ClassNotFoundException
{
// [JACKSON-597]: support primitive types (and void)
if (className.indexOf('.') < 0) {
if ("int".equals(className)) return Integer.TYPE;
if ("long".equals(className)) return Long.TYPE;
if ("float".equals(className)) return Float.TYPE;
if ("double".equals(className)) return Double.TYPE;
if ("boolean".equals(className)) return Boolean.TYPE;
if ("byte".equals(className)) return Byte.TYPE;
if ("char".equals(className)) return Character.TYPE;
if ("short".equals(className)) return Short.TYPE;
if ("void".equals(className)) return Void.TYPE;
}
// Two-phase lookup: first using context ClassLoader; then default
Throwable prob = null;
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader != null) {
try {
return Class.forName(className, true, loader);
} catch (Exception e) {
prob = getRootCause(e);
}
}
try {
return Class.forName(className);
} catch (Exception e) {
if (prob == null) {
prob = getRootCause(e);
}
}
if (prob instanceof RuntimeException) {
throw (RuntimeException) prob;
}
throw new ClassNotFoundException(prob.getMessage(), prob);
}
/*
/**********************************************************
/* Method type detection methods
/**********************************************************
*/
public static boolean hasGetterSignature(Method m)
{
// First: static methods can't be getters
if (Modifier.isStatic(m.getModifiers())) {
return false;
}
// Must take no args
Class<?>[] pts = m.getParameterTypes();
if (pts != null && pts.length != 0) {
return false;
}
// Can't be a void method
if (Void.TYPE == m.getReturnType()) {
return false;
}
// Otherwise looks ok:
return true;
}
/*
/**********************************************************
/* Exception handling
/**********************************************************
*/
/**
* Method that can be used to find the "root cause", innermost
* of chained (wrapped) exceptions.
*/
public static Throwable getRootCause(Throwable t)
{
while (t.getCause() != null) {
t = t.getCause();
}
return t;
}
/**
* Method that will unwrap root causes of given Throwable, and throw
* the innermost {@link Exception} or {@link Error} as is.
* This is useful in cases where mandatory wrapping is added, which
* is often done by Reflection API.
*/
public static void throwRootCause(Throwable t) throws Exception
{
t = getRootCause(t);
if (t instanceof Exception) {
throw (Exception) t;
}
throw (Error) t;
}
/**
* Method that will wrap 't' as an {@link IllegalArgumentException} if it
* is a checked exception; otherwise (runtime exception or error) throw as is
*/
public static void throwAsIAE(Throwable t)
{
throwAsIAE(t, t.getMessage());
}
/**
* Method that will wrap 't' as an
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> {@link IllegalArgumentException} (and with
* specified message) if it
* is a checked exception; otherwise (runtime exception or error) throw as is
*/
public static void throwAsIAE(Throwable t, String msg)
{
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
if (t instanceof Error) {
throw (Error) t;
}
throw new IllegalArgumentException(msg, t);
}
/**
* Method that will locate the innermost exception for given Throwable;
* and then wrap it as an {@link IllegalArgumentException} if it
* is a checked exception; otherwise (runtime exception or error) throw as is
*/
public static void unwrapAndThrowAsIAE(Throwable t)
{
throwAsIAE(getRootCause(t));
}
/**
* Method that will locate the innermost exception for given Throwable;
* and then wrap it as an {@link IllegalArgumentException} if it
* is a checked exception; otherwise (runtime exception or error) throw as is
*/
public static void unwrapAndThrowAsIAE(Throwable t, String msg)
{
throwAsIAE(getRootCause(t), msg);
}
/*
/**********************************************************
/* Instantiation
/**********************************************************
*/
/**
* Method that can be called to try to create an instantiate of
* specified type. Instantiation is done using default no-argument
* constructor.
*
* @param canFixAccess Whether it is possible to try to change access
* rights of the default constructor (in case it is not publicly
* accessible) or not.
*
* @throws IllegalArgumentException If instantiation fails for any reason;
* except for cases where constructor throws an unchecked exception
* (which will be passed as is)
*/
public static <T> T createInstance(Class<T> cls, boolean canFixAccess)
throws IllegalArgumentException
{
Constructor<T> ctor = findConstructor(cls, canFixAccess);
if (ctor == null) {
throw new IllegalArgumentException("Class "+cls.getName()+" has no default (no arg) constructor");
}
try {
return ctor.newInstance();
} catch (Exception e) {
ClassUtil.unwrapAndThrowAsIAE(e, "Failed to instantiate class "+cls.getName()+", problem: "+e.getMessage());
return null;
}
}
public static <T> Constructor<T> findConstructor(Class<T> cls, boolean canFixAccess)
throws IllegalArgumentException
{
try {
Constructor<T> ctor = cls.getDeclaredConstructor();
if (canFixAccess) {
checkAndFixAccess(ctor);
} else {
// Has to be public...
if (!Modifier.isPublic(ctor.getModifiers())) {
throw new IllegalArgumentException("Default constructor for "+cls.getName()+" is not accessible (non-public?): not allowed to try modify access via Reflection: can not instantiate type");
}
}
return ctor;
} catch (NoSuchMethodException e) {
;
} catch (Exception e) {
ClassUtil.unwrapAndThrowAsIAE(e, "Failed to find default constructor of class "+cls.getName()+", problem: "+e.getMessage());
}
return null;
}
/*
/**********************************************************
/* Primitive type support
/**********************************************************
*/
/**
* Helper method used to get default value for wrappers used for primitive
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>);
}
@SuppressWarnings("deprecation")
public final static boolean isBogusClass(Class<?> cls) {
return (cls == Void.class || cls == Void.TYPE
|| cls == com.fasterxml.jackson.databind.annotation.NoClass.class);
}
/*
/**********************************************************
/* Helper classes
/**********************************************************
*/
/**
* Inner class used to contain gory details of how we can determine
* details of instances of common JDK types like {@link EnumMap}s.
*/
private static class EnumTypeLocator
{
final static EnumTypeLocator instance = new EnumTypeLocator();
private final Field enumSetTypeField;
private final Field enumMapTypeField;
private EnumTypeLocator() {
/* JDK uses following fields to store information about actual Enumeration
* type for EnumSets, EnumMaps...
*/
enumSetTypeField = locateField(EnumSet.class, "elementType", Class.class);
enumMapTypeField = locateField(EnumMap.class, "elementType", Class.class);
}
@SuppressWarnings("unchecked")
public Class<? extends Enum<?>> enumTypeFor(EnumSet<?> set)
{
if (enumSetTypeField != null) {
return (Class<? extends Enum<?>>) get(set, enumSetTypeField);
}
throw new IllegalStateException("Can not figure out type for EnumSet (odd JDK platform?)");
}
@SuppressWarnings("unchecked")
public Class<? extends Enum<?>> enumTypeFor(EnumMap<?,?> set)
{
if (enumMapTypeField != null) {
return (Class<? extends Enum<?>>) get(set, enumMapTypeField);
}
throw new IllegalStateException("Can not figure out type for EnumMap (odd JDK platform?)");
}
private Object get(Object bean, Field field)
{
try {
return field.get(bean);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
private static Field locateField(Class<?> fromClass, String expectedName, Class<?> type)
{
Field found = null;
// First: let's see if we can find exact match:
Field[] fields = fromClass.getDeclaredFields();
for (Field f : fields) {
if (expectedName.equals(f.getName()) && f.getType() == type) {
found = f;
break;
}
}
// And if not, if there is just one field with the type, that field
if (found == null) {
for (Field f : fields) {
if (f.getType() == type) {
// If more than one, can't choose
if (found != null) return null;
found = f;
}
}
}
if (found != null) { // it's non-public, need to force accessible
try {
found.setAccessible(true);
} catch (Throwable t) { }
}
return found;
}
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>2.1
*/
public void replaceProperty(SettableBeanProperty original,
SettableBeanProperty replacement)
{
_beanProperties.replace(replacement);
}
/*
/**********************************************************
/* Partial deserializer implementation
/**********************************************************
*/
/**
* General version used when handling needs more advanced
* features.
*/
public abstract Object deserializeFromObject(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException;
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
// 16-Feb-2012, tatu: ObjectId may be used as well... need to check that first
if (_objectIdReader != null) {
// 05-Aug-2013, tatu: May use native Object Id
if (jp.canReadObjectId()) {
Object id = jp.getObjectId();
if (id != null) {
Object ob = typeDeserializer.deserializeTypedFromObject(jp, ctxt);
return _handleTypedObjectId(jp, ctxt, ob, id);
}
}
// or, Object Ids Jackson explicitly sets
JsonToken t = jp.getCurrentToken();
// for now (2.2.x) we only allow scalar types (Strings, integral numbers):
// NOTE: may need to allow handling of structured values in future for JSOG
if (t != null && t.isScalarValue()) {
return deserializeFromObjectId(jp, ctxt);
}
}
// In future could check current token... for now this should be enough:
return typeDeserializer.deserializeTypedFromObject(jp, ctxt);
}
/**
* Offlined method called to handle "native" Object Id that has been read
* and known to be associated with given deserialized POJO.
*
* @since 2.3
*/
protected Object _handleTypedObjectId(JsonParser jp, DeserializationContext ctxt,
Object pojo, Object rawId)
throws IOException, JsonProcessingException
{
/* 07-Aug-2013, tatu: One more challenge: type of id may not be type
* of property we are expecting later on; specifically, numeric ids
* vs Strings.
*/
JsonDeserializer<Object> idDeser = _objectIdReader.getDeserializer();
final Object id;
// Ok, this is bit ridiculous; let's see if conversion is needed:
if (idDeser.handledType() == rawId.getClass()) {
// nope: already same type
id = rawId;
} else {
id = _convertObjectId(jp, ctxt, rawId, idDeser);
}
ReadableObjectId roid = ctxt.findObjectId(id, _objectIdReader.generator, _objectIdReader.resolver);
roid.bindItem(pojo);
// also: may need to set a property value as well
SettableBeanProperty idProp = _objectIdReader.idProperty;
if (idProp != null) {
return idProp.setAndReturn(pojo, id);
}
return pojo;
}
/**
* Helper method we need to do necessary conversion from whatever native object id
* type is, into declared type that Jackson internals expect. This may be
* simple cast (for String ids), or something
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> more complicated; in latter
* case we may need to create bogus content buffer to allow use of
* id deserializer.
*
* @since 2.3
*/
@SuppressWarnings("resource") // TokenBuffers don't need close, nor parser thereof
protected Object _convertObjectId(JsonParser jp, DeserializationContext ctxt,
Object rawId, JsonDeserializer<Object> idDeser) throws IOException
{
TokenBuffer buf = new TokenBuffer(jp);
if (rawId instanceof String) {
buf.writeString((String) rawId);
} else if (rawId instanceof Long) {
buf.writeNumber(((Long) rawId).longValue());
} else if (rawId instanceof Integer) {
buf.writeNumber(((Integer) rawId).intValue());
} else {
// should we worry about UUIDs? They should be fine, right?
// 07-Aug-2014, tatu: Maybe, but not necessarily; had issues with
// Smile format; [Smile#19], possibly related.
buf.writeObject(rawId);
}
JsonParser bufParser = buf.asParser();
bufParser.nextToken();
return idDeser.deserialize(bufParser, ctxt);
}
// NOTE: currently only used by standard BeanDeserializer (not Builder-based)
/**
* Alternative deserialization method used when we expect to see Object Id;
* if so, we will need to ensure that the Id is seen before anything
* else, to ensure that it is available for solving references,
* even if JSON itself is not ordered that way. This may require
* buffering in some cases, but usually just a simple lookup to ensure
* that ordering is correct.
*/
protected Object deserializeWithObjectId(JsonParser jp, DeserializationContext ctxt) throws IOException
{
return deserializeFromObject(jp, ctxt);
}
/**
* Method called in cases where it looks like we got an Object Id
* to parse and use as a reference.
*/
protected Object deserializeFromObjectId(JsonParser jp, DeserializationContext ctxt) throws IOException
{
Object id = _objectIdReader.readObjectReference(jp, ctxt);
ReadableObjectId roid = ctxt.findObjectId(id, _objectIdReader.generator, _objectIdReader.resolver);
// do we have it resolved?
Object pojo = roid.resolve();
if (pojo == null) { // not yet; should wait...
throw new UnresolvedForwardReference("Could not resolve Object Id ["+id+"] (for "
+_beanType+").", jp.getCurrentLocation(), roid);
}
return pojo;
}
protected Object deserializeFromObjectUsingNonDefault(JsonParser jp,
DeserializationContext ctxt) throws IOException
{
if (_delegateDeserializer != null) {
return _valueInstantiator.createUsingDelegate(ctxt,
_delegateDeserializer.deserialize(jp, ctxt));
}
if (_propertyBasedCreator != null) {
return _deserializeUsingPropertyBased(jp, ctxt);
}
// should only occur for abstract types...
if (_beanType.isAbstract()) {
throw JsonMappingException.from(jp, "Can not instantiate abstract type "+_beanType
+" (need to add/enable type information?)");
}
throw JsonMappingException.from(jp, "No suitable constructor found for type "
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
}
}
return _valueInstantiator.createFromDouble(ctxt, jp.getDoubleValue());
}
// actually, could also be BigDecimal, so:
if (_delegateDeserializer != null) {
return _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt));
}
throw ctxt.instantiationException(getBeanClass(), "no suitable creator method found to deserialize from JSON floating-point number");
}
/**
* Method called to deserialize POJO value from a JSON boolean value (true, false)
*/
public Object deserializeFromBoolean(JsonParser jp, DeserializationContext ctxt) throws IOException
{
if (_delegateDeserializer != null) {
if (!_valueInstantiator.canCreateFromBoolean()) {
Object bean = _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt));
if (_injectables != null) {
injectValues(ctxt, bean);
}
return bean;
}
}
boolean value = (jp.getCurrentToken() == JsonToken.VALUE_TRUE);
return _valueInstantiator.createFromBoolean(ctxt, value);
}
public Object deserializeFromArray(JsonParser jp, DeserializationContext ctxt) throws IOException
{
if (_delegateDeserializer != null) {
try {
Object bean = _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt));
if (_injectables != null) {
injectValues(ctxt, bean);
}
return bean;
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
}
} else if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final Object value = deserialize(jp, ctxt);
if (jp.nextToken() != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single '" + _valueClass.getName() + "' value but there was more than a single value in the array");
}
return value;
}
throw ctxt.mappingException(getBeanClass());
}
public Object deserializeFromEmbedded(JsonParser jp, DeserializationContext ctxt) throws IOException
{
// First things first: id Object Id is used, most likely that's it; specifically,
// true for UUIDs when written as binary (with Smile, other binary formats)
if (_objectIdReader != null) {
return deserializeFromObjectId(jp, ctxt);
}
// TODO: maybe add support for ValueInstantiator, embedded?
return jp.getEmbeddedObject();
}
/*
/**********************************************************
/* Overridable helper methods
/**********************************************************
*/
protected void injectValues(DeserializationContext ctxt, Object bean)
throws IOException, JsonProcessingException
{
for (ValueInjector injector : _injectables) {
injector.inject(ctxt, bean);
}
}
/**
* Method called to handle set of one or more unknown properties,
* stored in their entirety in given {@link TokenBuffer}
* (as field entries, name and value).
*/
@SuppressWarnings("resource")
protected Object handleUnknownProperties(DeserializationContext ctxt,
Object bean, TokenBuffer unknownTokens)
throws IOException, JsonProcessingException
{
// First: add closing END_OBJECT as marker
unknownTokens.writeEnd
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>Object();
// note: buffer does NOT have starting START_OBJECT
JsonParser bufferParser = unknownTokens.asParser();
while (bufferParser.nextToken() != JsonToken.END_OBJECT) {
String propName = bufferParser.getCurrentName();
// Unknown: let's call handler method
bufferParser.nextToken();
handleUnknownProperty(bufferParser, ctxt, bean, propName);
}
return bean;
}
/**
* Helper method called for an unknown property, when using "vanilla"
* processing.
*/
protected void handleUnknownVanilla(JsonParser jp, DeserializationContext ctxt,
Object bean, String propName)
throws IOException, JsonProcessingException
{
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, bean, propName);
} else if (_anySetter != null) {
try {
// should we consider return type of any setter?
_anySetter.deserializeAndSet(jp, ctxt, bean, propName);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
} else {
// Unknown: let's call handler method
handleUnknownProperty(jp, ctxt, bean, propName);
}
}
/**
* Method called when a JSON property is encountered that has not matching
* setter, any-setter or field, and thus can not be assigned.
*/
@Override
protected void handleUnknownProperty(JsonParser jp, DeserializationContext ctxt,
Object beanOrClass, String propName)
throws IOException, JsonProcessingException
{
if (_ignoreAllUnknown) {
jp.skipChildren();
return;
}
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, beanOrClass, propName);
}
// Otherwise use default handling (call handler(s); if not
// handled, throw exception or skip depending on settings)
super.handleUnknownProperty(jp, ctxt, beanOrClass, propName);
}
/**
* Method called when an explicitly ignored property (one specified with a
* name to match, either by property annotation or class annotation) is encountered.
*
* @since 2.3
*/
protected void handleIgnoredProperty(JsonParser jp, DeserializationContext ctxt,
Object beanOrClass, String propName)
throws IOException, JsonProcessingException
{
if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES)) {
throw IgnoredPropertyException.from(jp, beanOrClass, propName, getKnownPropertyNames());
}
jp.skipChildren();
}
/**
* Method called in cases where we may have polymorphic deserialization
* case: that is, type of Creator-constructed bean is not the type
* of deserializer itself. It should be a sub-class or implementation
* class; either way, we may have more specific deserializer to use
* for handling it.
*
* @param jp (optional) If not null, parser that has more properties to handle
* (in addition to buffered properties); if null, all properties are passed
* in buffer
*/
@SuppressWarnings("resource")
protected Object handlePolymorphic(JsonParser jp, DeserializationContext ctxt,
Object bean, Token
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>Buffer unknownTokens)
throws IOException, JsonProcessingException
{
// First things first: maybe there is a more specific deserializer available?
JsonDeserializer<Object> subDeser = _findSubclassDeserializer(ctxt, bean, unknownTokens);
if (subDeser != null) {
if (unknownTokens != null) {
// need to add END_OBJECT marker first
unknownTokens.writeEndObject();
JsonParser p2 = unknownTokens.asParser();
p2.nextToken(); // to get to first data field
bean = subDeser.deserialize(p2, ctxt, bean);
}
// Original parser may also have some leftovers
if (jp != null) {
bean = subDeser.deserialize(jp, ctxt, bean);
}
return bean;
}
// nope; need to use this deserializer. Unknowns we've seen so far?
if (unknownTokens != null) {
bean = handleUnknownProperties(ctxt, bean, unknownTokens);
}
// and/or things left to process via main parser?
if (jp != null) {
bean = deserialize(jp, ctxt, bean);
}
return bean;
}
/**
* Helper method called to (try to) locate deserializer for given sub-type of
* type that this deserializer handles.
*/
protected JsonDeserializer<Object> _findSubclassDeserializer(DeserializationContext ctxt,
Object bean, TokenBuffer unknownTokens)
throws IOException, JsonProcessingException
{
JsonDeserializer<Object> subDeser;
// First: maybe we have already created sub-type deserializer?
synchronized (this) {
subDeser = (_subDeserializers == null) ? null : _subDeserializers.get(new ClassKey(bean.getClass()));
}
if (subDeser != null) {
return subDeser;
}
// If not, maybe we can locate one. First, need provider
JavaType type = ctxt.constructType(bean.getClass());
/* 30-Jan-2012, tatu: Ideally we would be passing referring
* property; which in theory we could keep track of via
* ResolvableDeserializer (if we absolutely must...).
* But for now, let's not bother.
*/
// subDeser = ctxt.findValueDeserializer(type, _property);
subDeser = ctxt.findRootValueDeserializer(type);
// Also, need to cache it
if (subDeser != null) {
synchronized (this) {
if (_subDeserializers == null) {
_subDeserializers = new HashMap<ClassKey,JsonDeserializer<Object>>();;
}
_subDeserializers.put(new ClassKey(bean.getClass()), subDeser);
}
}
return subDeser;
}
/*
/**********************************************************
/* Helper methods for error reporting
/**********************************************************
*/
/**
* Method that will modify caught exception (passed in as argument)
* as necessary to include reference information, and to ensure it
* is a subtype of {@link IOException}, or an unchecked exception.
*<p>
* Rules for wrapping and unwrapping are bit complicated; essentially:
*<ul>
* <li>Errors are to be passed as is (if uncovered via unwrapping)
* <li>"Plain" IOExceptions (ones that are
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> not of type
* {@link JsonMappingException} are to be passed as is
*</ul>
*/
public void wrapAndThrow(Throwable t, Object bean, String fieldName, DeserializationContext ctxt)
throws IOException
{
// [JACKSON-55] Need to add reference information
throw JsonMappingException.wrapWithPath(throwOrReturnThrowable(t, ctxt), bean, fieldName);
}
@Deprecated // since 2.4, not used by core Jackson; only relevant for arrays/Collections
public void wrapAndThrow(Throwable t, Object bean, int index, DeserializationContext ctxt) throws IOException {
// [JACKSON-55] Need to add reference information
throw JsonMappingException.wrapWithPath(throwOrReturnThrowable(t, ctxt), bean, index);
}
private Throwable throwOrReturnThrowable(Throwable t, DeserializationContext ctxt)
throws IOException
{
/* 05-Mar-2009, tatu: But one nasty edge is when we get
* StackOverflow: usually due to infinite loop. But that
* often gets hidden within an InvocationTargetException...
*/
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors to be passed as is
if (t instanceof Error) {
throw (Error) t;
}
boolean wrap = (ctxt == null) || ctxt.isEnabled(DeserializationFeature.WRAP_EXCEPTIONS);
// Ditto for IOExceptions; except we may want to wrap JSON exceptions
if (t instanceof IOException) {
if (!wrap || !(t instanceof JsonProcessingException)) {
throw (IOException) t;
}
} else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
}
return t;
}
protected void wrapInstantiationProblem(Throwable t, DeserializationContext ctxt)
throws IOException
{
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors and "plain" IOExceptions to be passed as is
if (t instanceof Error) {
throw (Error) t;
}
boolean wrap = (ctxt == null) || ctxt.isEnabled(DeserializationFeature.WRAP_EXCEPTIONS);
if (t instanceof IOException) {
// Since we have no more information to add, let's not actually wrap..
throw (IOException) t;
} else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
}
throw ctxt.instantiationException(_beanType.getRawClass(), t);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* This concrete value class is used to contain boolean (true / false)
* values. Only two instances are ever created, to minimize memory
* usage.
*/
public class BooleanNode
extends ValueNode
{
// // Just need two instances...
public final static BooleanNode TRUE = new BooleanNode(true);
public final static BooleanNode FALSE = new BooleanNode(false);
private final boolean _value;
private BooleanNode(boolean v) { _value = v; }
public static BooleanNode getTrue() { return TRUE; }
public static BooleanNode getFalse() { return FALSE; }
public static BooleanNode valueOf(boolean b) { return b ? TRUE : FALSE; }
@Override
public JsonNodeType getNodeType() {
return JsonNodeType.BOOLEAN;
}
@Override public JsonToken asToken() {
return _value ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE;
}
@Override
public boolean booleanValue() {
return _value;
}
@Override
public String asText() {
return _value ? "true" : "false";
}
@Override
public boolean asBoolean() {
return _value;
}
@Override
public boolean asBoolean(boolean defaultValue) {
return _value;
}
@Override
public int asInt(int defaultValue) {
return _value ? 1 : 0;
}
@Override
public long asLong(long defaultValue) {
return _value ? 1L : 0L;
}
@Override
public double asDouble(double defaultValue) {
return _value ? 1.0 : 0.0;
}
@Override
public final void serialize(JsonGenerator jg, SerializerProvider provider)
throws IOException, JsonProcessingException
{
jg.writeBoolean(_value);
}
@Override
public boolean equals(Object o)
{
/* 11-Mar-2013, tatu: Apparently ClassLoaders can manage to load
* different instances, rendering identity comparisons broken.
* So let's use value instead.
*/
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof BooleanNode)) {
return false;
}
return (_value == ((BooleanNode) o)._value);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> (String str : moreToIgnore) {
ignored.add(str);
}
}
}
return withResolved(kd, vtd, vd, ignored);
}
/*
/**********************************************************
/* ContainerDeserializerBase API
/**********************************************************
*/
@Override
public JavaType getContentType() {
return _mapType.getContentType();
}
@Override
public JsonDeserializer<Object> getContentDeserializer() {
return _valueDeserializer;
}
/*
/**********************************************************
/* JsonDeserializer API
/**********************************************************
*/
@Override
@SuppressWarnings("unchecked")
public Map<Object,Object> deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (_propertyBasedCreator != null) {
return _deserializeUsingCreator(jp, ctxt);
}
if (_delegateDeserializer != null) {
return (Map<Object,Object>) _valueInstantiator.createUsingDelegate(ctxt,
_delegateDeserializer.deserialize(jp, ctxt));
}
if (!_hasDefaultCreator) {
throw ctxt.instantiationException(getMapClass(), "No default constructor found");
}
// Ok: must point to START_OBJECT, FIELD_NAME or END_OBJECT
JsonToken t = jp.getCurrentToken();
if (t != JsonToken.START_OBJECT && t != JsonToken.FIELD_NAME && t != JsonToken.END_OBJECT) {
// [JACKSON-620] (empty) String may be ok however:
if (t == JsonToken.VALUE_STRING) {
return (Map<Object,Object>) _valueInstantiator.createFromString(ctxt, jp.getText());
}
throw ctxt.mappingException(getMapClass());
}
final Map<Object,Object> result = (Map<Object,Object>) _valueInstantiator.createUsingDefault(ctxt);
if (_standardStringKey) {
_readAndBindStringMap(jp, ctxt, result);
return result;
}
_readAndBind(jp, ctxt, result);
return result;
}
@Override
public Map<Object,Object> deserialize(JsonParser jp, DeserializationContext ctxt,
Map<Object,Object> result)
throws IOException, JsonProcessingException
{
// Ok: must point to START_OBJECT or FIELD_NAME
JsonToken t = jp.getCurrentToken();
if (t != JsonToken.START_OBJECT && t != JsonToken.FIELD_NAME) {
throw ctxt.mappingException(getMapClass());
}
if (_standardStringKey) {
_readAndBindStringMap(jp, ctxt, result);
return result;
}
_readAndBind(jp, ctxt, result);
return result;
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
// In future could check current token... for now this should be enough:
return typeDeserializer.deserializeTypedFromObject(jp, ctxt);
}
/*
/**********************************************************
/* Other public accessors
/**********************************************************
*/
@SuppressWarnings("unchecked")
public final Class<?> getMapClass() { return (Class<Map<Object,Object>>) _mapType.getRawClass(); }
@Override public JavaType getValueType() { return _mapType; }
/*
/**********************************************************
/* Internal methods
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> /**********************************************************
*/
protected final void _readAndBind(JsonParser jp, DeserializationContext ctxt,
Map<Object,Object> result)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.START_OBJECT) {
t = jp.nextToken();
}
final KeyDeserializer keyDes = _keyDeserializer;
final JsonDeserializer<Object> valueDes = _valueDeserializer;
final TypeDeserializer typeDeser = _valueTypeDeserializer;
MapReferringAccumulator referringAccumulator = null;
boolean useObjectId = valueDes.getObjectIdReader() != null;
if (useObjectId) {
referringAccumulator = new MapReferringAccumulator(_mapType.getContentType().getRawClass(), result);
}
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
// Must point to field name
String fieldName = jp.getCurrentName();
Object key = keyDes.deserializeKey(fieldName, ctxt);
// And then the value...
t = jp.nextToken();
if (_ignorableProperties != null && _ignorableProperties.contains(fieldName)) {
jp.skipChildren();
continue;
}
try{
// Note: must handle null explicitly here; value deserializers won't
Object value;
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue();
} else if (typeDeser == null) {
value = valueDes.deserialize(jp, ctxt);
} else {
value = valueDes.deserializeWithType(jp, ctxt, typeDeser);
}
/* !!! 23-Dec-2008, tatu: should there be an option to verify
* that there are no duplicate field names? (and/or what
* to do, keep-first or keep-last)
*/
if (useObjectId) {
referringAccumulator.put(key, value);
} else {
result.put(key, value);
}
} catch (UnresolvedForwardReference reference) {
handleUnresolvedReference(jp, referringAccumulator, key, reference);
} catch (Exception e) {
wrapAndThrow(e, result, fieldName);
}
}
}
/**
* Optimized method used when keys can be deserialized as plain old
* {@link java.lang.String}s, and there is no custom deserialized
* specified.
*/
protected final void _readAndBindStringMap(JsonParser jp, DeserializationContext ctxt,
Map<Object,Object> result)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.START_OBJECT) {
t = jp.nextToken();
}
final JsonDeserializer<Object> valueDes = _valueDeserializer;
final TypeDeserializer typeDeser = _valueTypeDeserializer;
MapReferringAccumulator referringAccumulator = null;
boolean useObjectId = valueDes.getObjectIdReader() != null;
if (useObjectId) {
referringAccumulator = new MapReferringAccumulator(_mapType.getContentType().getRawClass(), result);
}
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
// Must point to field name
String fieldName = jp.getCurrentName();
// And then the value...
t = jp.nextToken();
if (_ignorableProperties != null &&
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> _ignorableProperties.contains(fieldName)) {
jp.skipChildren();
continue;
}
try {
// Note: must handle null explicitly here; value deserializers won't
Object value;
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue();
} else if (typeDeser == null) {
value = valueDes.deserialize(jp, ctxt);
} else {
value = valueDes.deserializeWithType(jp, ctxt, typeDeser);
}
if (useObjectId) {
referringAccumulator.put(fieldName, value);
} else {
result.put(fieldName, value);
}
} catch (UnresolvedForwardReference reference) {
handleUnresolvedReference(jp, referringAccumulator, fieldName, reference);
} catch (Exception e) {
wrapAndThrow(e, result, fieldName);
}
}
}
@SuppressWarnings("unchecked")
public Map<Object,Object> _deserializeUsingCreator(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
final PropertyBasedCreator creator = _propertyBasedCreator;
// null -> no ObjectIdReader for Maps (yet?)
PropertyValueBuffer buffer = creator.startBuilding(jp, ctxt, null);
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.START_OBJECT) {
t = jp.nextToken();
}
final JsonDeserializer<Object> valueDes = _valueDeserializer;
final TypeDeserializer typeDeser = _valueTypeDeserializer;
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
t = jp.nextToken(); // to get to value
if (_ignorableProperties != null && _ignorableProperties.contains(propName)) {
jp.skipChildren(); // and skip it (in case of array/object)
continue;
}
// creator property?
SettableBeanProperty prop = creator.findCreatorProperty(propName);
if (prop != null) {
// Last property to set?
Object value = prop.deserialize(jp, ctxt);
if (buffer.assignParameter(prop.getCreatorIndex(), value)) {
jp.nextToken();
Map<Object,Object> result;
try {
result = (Map<Object,Object>)creator.build(ctxt, buffer);
} catch (Exception e) {
wrapAndThrow(e, _mapType.getRawClass(), propName);
return null;
}
_readAndBind(jp, ctxt, result);
return result;
}
continue;
}
// other property? needs buffering
String fieldName = jp.getCurrentName();
Object key = _keyDeserializer.deserializeKey(fieldName, ctxt);
Object value;
try {
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue();
} else if (typeDeser == null) {
value = valueDes.deserialize(jp, ctxt);
} else {
value = valueDes.deserializeWithType(jp, ctxt, typeDeser);
}
} catch (Exception e) {
wrapAndThrow(e, _mapType.getRawClass(), propName);
return null;
}
buffer.bufferMapProperty(key, value);
}
// end of JSON object?
// if so, can just construct and
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> leave...
try {
return (Map<Object,Object>)creator.build(ctxt, buffer);
} catch (Exception e) {
wrapAndThrow(e, _mapType.getRawClass(), null);
return null;
}
}
@Deprecated // since 2.5
protected void wrapAndThrow(Throwable t, Object ref) throws IOException {
wrapAndThrow(t, ref, null);
}
// note: copied from BeanDeserializer; should try to share somehow...
protected void wrapAndThrow(Throwable t, Object ref, String key) throws IOException
{
// to handle StackOverflow:
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors and "plain" IOExceptions to be passed as is
if (t instanceof Error) {
throw (Error) t;
}
// ... except for mapping exceptions
if (t instanceof IOException && !(t instanceof JsonMappingException)) {
throw (IOException) t;
}
throw JsonMappingException.wrapWithPath(t, ref, key);
}
private void handleUnresolvedReference(JsonParser jp, MapReferringAccumulator accumulator, Object key,
UnresolvedForwardReference reference)
throws JsonMappingException
{
if (accumulator == null) {
throw JsonMappingException.from(jp, "Unresolved forward reference but no identity info.", reference);
}
Referring referring = accumulator.handleUnresolvedReference(reference, key);
reference.getRoid().appendReferring(referring);
}
private final static class MapReferringAccumulator {
private final Class<?> _valueType;
private Map<Object,Object> _result;
/**
* A list of {@link MapReferring} to maintain ordering.
*/
private List<MapReferring> _accumulator = new ArrayList<MapReferring>();
public MapReferringAccumulator(Class<?> valueType, Map<Object, Object> result) {
_valueType = valueType;
_result = result;
}
public void put(Object key, Object value)
{
if (_accumulator.isEmpty()) {
_result.put(key, value);
} else {
MapReferring ref = _accumulator.get(_accumulator.size() - 1);
ref.next.put(key, value);
}
}
public Referring handleUnresolvedReference(UnresolvedForwardReference reference, Object key)
{
MapReferring id = new MapReferring(this, reference, _valueType, key);
_accumulator.add(id);
return id;
}
public void resolveForwardReference(Object id, Object value) throws IOException
{
Iterator<MapReferring> iterator = _accumulator.iterator();
// Resolve ordering after resolution of an id. This means either:
// 1- adding to the result map in case of the first unresolved id.
// 2- merge the content of the resolved id with its previous unresolved id.
Map<Object,Object> previous = _result;
while (iterator.hasNext()) {
MapReferring ref = iterator.next();
if (ref.hasId(id)) {
iterator.remove();
previous.put(ref.key, value);
previous.putAll(ref.next);
return;
}
previous = ref.next;
}
throw new IllegalArgumentException("Trying to resolve
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> a forward reference with id [" + id
+ "] that wasn't previously seen as unresolved.");
}
}
/**
* Helper class to maintain processing order of value. The resolved
* object associated with {@link #_id} comes before the values in
* {@link _next}.
*/
private final static class MapReferring extends Referring {
private final MapReferringAccumulator _parent;
public final Map<Object, Object> next = new LinkedHashMap<Object, Object>();
public final Object key;
private MapReferring(MapReferringAccumulator parent, UnresolvedForwardReference ref,
Class<?> valueType, Object key)
{
super(ref, valueType);
_parent = parent;
this.key = key;
}
@Override
public void handleResolvedForwardReference(Object id, Object value) throws IOException {
_parent.resolveForwardReference(id, value);
}
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
}
@Override
public BuilderBasedDeserializer withIgnorableProperties(HashSet<String> ignorableProps) {
return new BuilderBasedDeserializer(this, ignorableProps);
}
@Override
protected BeanAsArrayBuilderDeserializer asArrayDeserializer() {
SettableBeanProperty[] props = _beanProperties.getPropertiesInInsertionOrder();
return new BeanAsArrayBuilderDeserializer(this, props, _buildMethod);
}
/*
/**********************************************************
/* JsonDeserializer implementation
/**********************************************************
*/
protected final Object finishBuild(DeserializationContext ctxt, Object builder)
throws IOException
{
try {
return _buildMethod.getMember().invoke(builder);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
return null;
}
}
/**
* Main deserialization method for bean-based objects (POJOs).
*/
@Override
public final Object deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
// common case first:
if (t == JsonToken.START_OBJECT) {
t = jp.nextToken();
if (_vanillaProcessing) {
return finishBuild(ctxt, vanillaDeserialize(jp, ctxt, t));
}
Object builder = deserializeFromObject(jp, ctxt);
return finishBuild(ctxt, builder);
}
// and then others, generally requiring use of @JsonCreator
switch (t) {
case VALUE_STRING:
return finishBuild(ctxt, deserializeFromString(jp, ctxt));
case VALUE_NUMBER_INT:
return finishBuild(ctxt, deserializeFromNumber(jp, ctxt));
case VALUE_NUMBER_FLOAT:
return finishBuild(ctxt, deserializeFromDouble(jp, ctxt));
case VALUE_EMBEDDED_OBJECT:
return jp.getEmbeddedObject();
case VALUE_TRUE:
case VALUE_FALSE:
return finishBuild(ctxt, deserializeFromBoolean(jp, ctxt));
case START_ARRAY:
// these only work if there's a (delegating) creator...
return finishBuild(ctxt, deserializeFromArray(jp, ctxt));
case FIELD_NAME:
case END_OBJECT: // added to resolve [JACKSON-319], possible related issues
return finishBuild(ctxt, deserializeFromObject(jp, ctxt));
default:
throw ctxt.mappingException(handledType());
}
}
/**
* Secondary deserialization method, called in cases where POJO
* instance is created as part of deserialization, potentially
* after collecting some or all of the properties to set.
*/
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt,
Object builder)
throws IOException, JsonProcessingException
{
/* Important: we call separate method which does NOT call
* 'finishBuild()', to avoid problems with recursion
*/
return finishBuild(ctxt, _deserialize(jp, ctxt, builder));
}
/*
/**********************************************************
/* Concrete deserialization methods
/**********************************************************
*/
protected final Object _deserialize(JsonParser jp,
DeserializationContext ctxt, Object builder)
throws IOException, JsonProcessingException
{
if (_injectables != null) {
injectValues(ctxt, builder);
}
if (_unwrappedPropertyHandler != null) {
return deserializeWithUnwrapped(jp, ctxt, builder);
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> if (_externalTypeIdHandler != null) {
return deserializeWithExternalTypeId(jp, ctxt, builder);
}
if (_needViewProcesing) {
Class<?> view = ctxt.getActiveView();
if (view != null) {
return deserializeWithView(jp, ctxt, builder, view);
}
}
JsonToken t = jp.getCurrentToken();
// 23-Mar-2010, tatu: In some cases, we start with full JSON object too...
if (t == JsonToken.START_OBJECT) {
t = jp.nextToken();
}
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
// Skip field name:
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
try {
builder = prop.deserializeSetAndReturn(jp, ctxt, builder);
} catch (Exception e) {
wrapAndThrow(e, builder, propName, ctxt);
}
continue;
}
handleUnknownVanilla(jp, ctxt, handledType(), propName);
}
return builder;
}
/**
* Streamlined version that is only used when no "special"
* features are enabled.
*/
private final Object vanillaDeserialize(JsonParser jp,
DeserializationContext ctxt, JsonToken t)
throws IOException, JsonProcessingException
{
Object bean = _valueInstantiator.createUsingDefault(ctxt);
for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) {
String propName = jp.getCurrentName();
// Skip field name:
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
try {
bean = prop.deserializeSetAndReturn(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
} else {
handleUnknownVanilla(jp, ctxt, bean, propName);
}
}
return bean;
}
/**
* General version used when handling needs more advanced
* features.
*/
@Override
public Object deserializeFromObject(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (_nonStandardCreation) {
if (_unwrappedPropertyHandler != null) {
return deserializeWithUnwrapped(jp, ctxt);
}
if (_externalTypeIdHandler != null) {
return deserializeWithExternalTypeId(jp, ctxt);
}
return deserializeFromObjectUsingNonDefault(jp, ctxt);
}
Object bean = _valueInstantiator.createUsingDefault(ctxt);
if (_injectables != null) {
injectValues(ctxt, bean);
}
if (_needViewProcesing) {
Class<?> view = ctxt.getActiveView();
if (view != null) {
return deserializeWithView(jp, ctxt, bean, view);
}
}
for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) {
String propName = jp.getCurrentName();
// Skip field name:
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> != null) { // normal case
try {
bean = prop.deserializeSetAndReturn(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
handleUnknownVanilla(jp, ctxt, bean, propName);
}
return bean;
}
/**
* Method called to deserialize bean using "property-based creator":
* this means that a non-default constructor or factory method is
* called, and then possibly other setters. The trick is that
* values for creator method need to be buffered, first; and
* due to non-guaranteed ordering possibly some other properties
* as well.
*/
@Override
@SuppressWarnings("resource")
protected final Object _deserializeUsingPropertyBased(final JsonParser jp,
final DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
final PropertyBasedCreator creator = _propertyBasedCreator;
PropertyValueBuffer buffer = creator.startBuilding(jp, ctxt, _objectIdReader);
// 04-Jan-2010, tatu: May need to collect unknown properties for polymorphic cases
TokenBuffer unknown = null;
JsonToken t = jp.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
jp.nextToken(); // to point to value
// creator property?
SettableBeanProperty creatorProp = creator.findCreatorProperty(propName);
if (creatorProp != null) {
// Last creator property to set?
Object value = creatorProp.deserialize(jp, ctxt);
if (buffer.assignParameter(creatorProp.getCreatorIndex(), value)) {
jp.nextToken(); // to move to following FIELD_NAME/END_OBJECT
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
continue; // never gets here
}
// polymorphic?
if (bean.getClass() != _beanType.getRawClass()) {
return handlePolymorphic(jp, ctxt, bean, unknown);
}
if (unknown != null) { // nope, just extra unknown stuff...
bean = handleUnknownProperties(ctxt, bean, unknown);
}
// or just clean?
return _deserialize(jp, ctxt, bean);
}
continue;
}
// Object Id property?
if (buffer.readIdProperty(propName)) {
continue;
}
// regular property? needs buffering
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) {
buffer.bufferProperty(prop, prop.deserialize(jp, ctxt));
continue;
}
// As per [JACKSON-313], things marked as ignorable should not be
// passed to any setter
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, handledType(), propName);
continue;
}
// "any property"?
if (_anySetter != null) {
buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(jp, ctxt));
continue;
}
// Ok then
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>, let's collect the whole field; name and value
if (unknown == null) {
unknown = new TokenBuffer(jp);
}
unknown.writeFieldName(propName);
unknown.copyCurrentStructure(jp);
}
// We hit END_OBJECT, so:
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
return null; // never gets here
}
if (unknown != null) {
// polymorphic?
if (bean.getClass() != _beanType.getRawClass()) {
return handlePolymorphic(null, ctxt, bean, unknown);
}
// no, just some extra unknown properties
return handleUnknownProperties(ctxt, bean, unknown);
}
return bean;
}
/*
/**********************************************************
/* Deserializing when we have to consider an active View
/**********************************************************
*/
protected final Object deserializeWithView(JsonParser jp, DeserializationContext ctxt,
Object bean, Class<?> activeView)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
// Skip field name:
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) {
if (!prop.visibleInView(activeView)) {
jp.skipChildren();
continue;
}
try {
bean = prop.deserializeSetAndReturn(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
handleUnknownVanilla(jp, ctxt, bean, propName);
}
return bean;
}
/*
/**********************************************************
/* Handling for cases where we have "unwrapped" values
/**********************************************************
*/
/**
* Method called when there are declared "unwrapped" properties
* which need special handling
*/
@SuppressWarnings("resource")
protected Object deserializeWithUnwrapped(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (_delegateDeserializer != null) {
return _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt));
}
if (_propertyBasedCreator != null) {
return deserializeUsingPropertyBasedWithUnwrapped(jp, ctxt);
}
TokenBuffer tokens = new TokenBuffer(jp);
tokens.writeStartObject();
Object bean = _valueInstantiator.createUsingDefault(ctxt);
if (_injectables != null) {
injectValues(ctxt, bean);
}
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) {
String propName = jp.getCurrentName();
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
if (activeView != null && !prop.visibleInView(activeView)) {
jp.skipChildren();
continue;
}
try {
bean = prop.deserializeSetAndReturn(jp, ctxt, bean);
} catch (
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
// ignorable things should be ignored
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, bean, propName);
continue;
}
// but... others should be passed to unwrapped property deserializers
tokens.writeFieldName(propName);
tokens.copyCurrentStructure(jp);
// how about any setter? We'll get copies but...
if (_anySetter != null) {
try {
_anySetter.deserializeAndSet(jp, ctxt, bean, propName);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
}
tokens.writeEndObject();
_unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens);
return bean;
}
@SuppressWarnings("resource")
protected Object deserializeWithUnwrapped(JsonParser jp,
DeserializationContext ctxt, Object bean)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.START_OBJECT) {
t = jp.nextToken();
}
TokenBuffer tokens = new TokenBuffer(jp);
tokens.writeStartObject();
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
SettableBeanProperty prop = _beanProperties.find(propName);
jp.nextToken();
if (prop != null) { // normal case
if (activeView != null && !prop.visibleInView(activeView)) {
jp.skipChildren();
continue;
}
try {
bean = prop.deserializeSetAndReturn(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, bean, propName);
continue;
}
// but... others should be passed to unwrapped property deserializers
tokens.writeFieldName(propName);
tokens.copyCurrentStructure(jp);
// how about any setter? We'll get copies but...
if (_anySetter != null) {
_anySetter.deserializeAndSet(jp, ctxt, bean, propName);
}
}
tokens.writeEndObject();
_unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens);
return bean;
}
@SuppressWarnings("resource")
protected Object deserializeUsingPropertyBasedWithUnwrapped(JsonParser jp,
DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
final PropertyBasedCreator creator = _propertyBasedCreator;
PropertyValueBuffer buffer = creator.startBuilding(jp, ctxt, _objectIdReader);
TokenBuffer tokens = new TokenBuffer(jp);
tokens.writeStartObject();
JsonToken t = jp.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
jp.nextToken(); // to point to value
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> // creator property?
SettableBeanProperty creatorProp = creator.findCreatorProperty(propName);
if (creatorProp != null) {
// Last creator property to set?
Object value = creatorProp.deserialize(jp, ctxt);
if (buffer.assignParameter(creatorProp.getCreatorIndex(), value)) {
t = jp.nextToken(); // to move to following FIELD_NAME/END_OBJECT
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
continue; // never gets here
}
// if so, need to copy all remaining tokens into buffer
while (t == JsonToken.FIELD_NAME) {
jp.nextToken(); // to skip name
tokens.copyCurrentStructure(jp);
t = jp.nextToken();
}
tokens.writeEndObject();
if (bean.getClass() != _beanType.getRawClass()) {
// !!! 08-Jul-2011, tatu: Could probably support; but for now
// it's too complicated, so bail out
throw ctxt.mappingException("Can not create polymorphic instances with unwrapped values");
}
return _unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens);
}
continue;
}
// Object Id property?
if (buffer.readIdProperty(propName)) {
continue;
}
// regular property? needs buffering
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) {
buffer.bufferProperty(prop, prop.deserialize(jp, ctxt));
continue;
}
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, handledType(), propName);
continue;
}
tokens.writeFieldName(propName);
tokens.copyCurrentStructure(jp);
// "any property"?
if (_anySetter != null) {
buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(jp, ctxt));
}
}
// We hit END_OBJECT, so:
Object bean;
// !!! 15-Feb-2012, tatu: Need to modify creator to use Builder!
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
return null; // never gets here
}
return _unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens);
}
/*
/**********************************************************
/* Handling for cases where we have property/-ies with
/* external type id
/**********************************************************
*/
protected Object deserializeWithExternalTypeId(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (_propertyBasedCreator != null) {
return deserializeUsingPropertyBasedWithExternalTypeId(jp, ctxt);
}
return deserializeWithExternalTypeId(jp, ctxt, _valueInstantiator.createUsingDefault(ctxt));
}
protected Object deserializeWithExternalTypeId(JsonParser jp,
DeserializationContext ctxt, Object bean)
throws IOException, JsonProcessingException
{
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> final ExternalTypeHandler ext = _externalTypeIdHandler.start();
for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) {
String propName = jp.getCurrentName();
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
if (activeView != null && !prop.visibleInView(activeView)) {
jp.skipChildren();
continue;
}
try {
bean = prop.deserializeSetAndReturn(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
// ignorable things should be ignored
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, bean, propName);
continue;
}
// but others are likely to be part of external type id thingy...
if (ext.handlePropertyValue(jp, ctxt, propName, bean)) {
continue;
}
// if not, the usual fallback handling:
if (_anySetter != null) {
try {
_anySetter.deserializeAndSet(jp, ctxt, bean, propName);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
} else {
// Unknown: let's call handler method
handleUnknownProperty(jp, ctxt, bean, propName);
}
}
// and when we get this far, let's try finalizing the deal:
return ext.complete(jp, ctxt, bean);
}
protected Object deserializeUsingPropertyBasedWithExternalTypeId(JsonParser jp,
DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// !!! 04-Mar-2012, TODO: Need to fix -- will not work as is...
throw new IllegalStateException("Deserialization with Builder, External type id, @JsonCreator not yet implemented");
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.impl;
import java.io.IOException;
import java.lang.reflect.Type;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
public class UnknownSerializer
extends StdSerializer<Object>
{
public UnknownSerializer() {
super(Object.class);
}
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonMappingException
{
// 27-Nov-2009, tatu: As per [JACKSON-201] may or may not fail...
if (provider.isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS)) {
failForEmpty(value);
}
// But if it's fine, we'll just output empty JSON Object:
jgen.writeStartObject();
jgen.writeEndObject();
}
@Override
public final void serializeWithType(Object value, JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer)
throws IOException, JsonGenerationException
{
if (provider.isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS)) {
failForEmpty(value);
}
typeSer.writeTypePrefixForObject(value, jgen);
typeSer.writeTypeSuffixForObject(value, jgen);
}
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException {
return null;
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
visitor.expectAnyFormat(typeHint);
}
protected void failForEmpty(Object value) throws JsonMappingException
{
throw new JsonMappingException("No serializer found for class "+value.getClass().getName()+" and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) )");
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.impl;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.util.Annotations;
/**
* This concrete sub-class implements Collection or Map property that is
* indirectly by getting the property value and directly modifying it.
*/
public final class SetterlessProperty
extends SettableBeanProperty
{
private static final long serialVersionUID = 1L;
protected final AnnotatedMethod _annotated;
/**
* Get method for accessing property value used to access property
* (of Collection or Map type) to modify.
*/
protected final Method _getter;
public SetterlessProperty(BeanPropertyDefinition propDef, JavaType type,
TypeDeserializer typeDeser, Annotations contextAnnotations, AnnotatedMethod method) {
super(propDef, type, typeDeser, contextAnnotations);
_annotated = method;
_getter = method.getAnnotated();
}
protected SetterlessProperty(SetterlessProperty src, JsonDeserializer<?> deser) {
super(src, deser);
_annotated = src._annotated;
_getter = src._getter;
}
protected SetterlessProperty(SetterlessProperty src, PropertyName newName) {
super(src, newName);
_annotated = src._annotated;
_getter = src._getter;
}
@Override
public SetterlessProperty withName(PropertyName newName) {
return new SetterlessProperty(this, newName);
}
@Override
public SetterlessProperty withValueDeserializer(JsonDeserializer<?> deser) {
return new SetterlessProperty(this, deser);
}
/*
/**********************************************************
/* BeanProperty impl
/**********************************************************
*/
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return _annotated.getAnnotation(acls);
}
@Override public AnnotatedMember getMember() { return _annotated; }
/*
/**********************************************************
/* Overridden methods
/**********************************************************
*/
@Override
public final void deserializeAndSet(JsonParser jp, DeserializationContext ctxt,
Object instance)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NULL) {
/* Hmmh. Is this a problem? We won't be setting anything, so it's
* equivalent of empty Collection/Map in this case
*/
return;
}
// For [#
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
@Override
public ObjectIdReader getObjectIdReader() {
return _objectIdReader;
}
/**
* Method called by <code>BeanDeserializer</code> to resolve back reference
* part of managed references.
*/
@Override
public SettableBeanProperty findBackReference(String logicalName) {
return (_backRefProperties == null) ? null : _backRefProperties.get(logicalName);
}
/*
/**********************************************************
/* Deserializer implementation
/**********************************************************
*/
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
// Hmmh. One tricky question; for scalar, is it an Object Id, or "Natural" type?
// for now, prefer Object Id:
if (_objectIdReader != null) {
JsonToken t = jp.getCurrentToken();
// should be good enough check; we only care about Strings, integral numbers:
if (t != null && t.isScalarValue()) {
return _deserializeFromObjectId(jp, ctxt);
}
}
// First: support "natural" values (which are always serialized without type info!)
Object result = _deserializeIfNatural(jp, ctxt);
if (result != null) {
return result;
}
return typeDeserializer.deserializeTypedFromObject(jp, ctxt);
}
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// This method should never be called...
throw ctxt.instantiationException(_baseType.getRawClass(),
"abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information");
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
protected Object _deserializeIfNatural(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
/* As per [JACKSON-417], there is a chance we might be "natural" types
* (String, Boolean, Integer, Double), which do not include any type information...
* Care must be taken to only return this if return type matches, however.
* Finally, we may have to consider possibility of custom handlers for
* these values: but for now this should work ok.
*/
/* 21-Sep-2013, tatu: It may seem odd that I'm not using a switch here.
* But turns out that a switch on an enum generates an inner class...
* crazy! So this is to avoid that, simply since new class weighs about 1kB
* after compression.
*/
final JsonToken t = jp.getCurrentToken();
if (t.isScalarValue()) {
if (t == JsonToken.VALUE_STRING) {
if (_acceptString) {
return jp.getText();
}
} else if (t == JsonToken.VALUE_NUMBER_INT) {
if (_acceptInt) {
return jp.getIntValue();
}
} else if (t == JsonToken.VALUE_NUMBER_FLOAT) {
if (_acceptDouble) {
return Double.valueOf(jp.getDoubleValue());
}
} else if (t == JsonToken.VALUE_TRUE) {
if (_acceptBoolean) {
return Boolean.TRUE;
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> else if (t == JsonToken.VALUE_FALSE) {
if (_acceptBoolean) {
return Boolean.FALSE;
}
}
}
return null;
}
/**
* Method called in cases where it looks like we got an Object Id
* to parse and use as a reference.
*/
protected Object _deserializeFromObjectId(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
Object id = _objectIdReader.readObjectReference(jp, ctxt);
ReadableObjectId roid = ctxt.findObjectId(id, _objectIdReader.generator, _objectIdReader.resolver);
// do we have it resolved?
Object pojo = roid.resolve();
if (pojo == null) { // not yet; should wait...
throw new IllegalStateException("Could not resolve Object Id ["+id+"] -- unresolved forward-reference?");
}
return pojo;
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>******************************************************
*/
@Override
public PropertyName findRootName(AnnotatedClass ac)
{
PropertyName name1 = _primary.findRootName(ac);
if (name1 == null) {
return _secondary.findRootName(ac);
}
if (name1.hasSimpleName()) {
return name1;
}
// name1 is empty; how about secondary?
PropertyName name2 = _secondary.findRootName(ac);
return (name2 == null) ? name1 : name2;
}
@Override
public String[] findPropertiesToIgnore(Annotated ac)
{
String[] result = _primary.findPropertiesToIgnore(ac);
if (result == null) {
result = _secondary.findPropertiesToIgnore(ac);
}
return result;
}
@Override
public Boolean findIgnoreUnknownProperties(AnnotatedClass ac)
{
Boolean result = _primary.findIgnoreUnknownProperties(ac);
if (result == null) {
result = _secondary.findIgnoreUnknownProperties(ac);
}
return result;
}
@Override
public Boolean isIgnorableType(AnnotatedClass ac)
{
Boolean result = _primary.isIgnorableType(ac);
if (result == null) {
result = _secondary.isIgnorableType(ac);
}
return result;
}
@Deprecated
@Override
public Object findFilterId(AnnotatedClass ac)
{
Object id = _primary.findFilterId(ac);
if (id == null) {
id = _secondary.findFilterId(ac);
}
return id;
}
@Override
public Object findFilterId(Annotated ann)
{
Object id = _primary.findFilterId(ann);
if (id == null) {
id = _secondary.findFilterId(ann);
}
return id;
}
@Override
public Object findNamingStrategy(AnnotatedClass ac)
{
Object str = _primary.findNamingStrategy(ac);
if (str == null) {
str = _secondary.findNamingStrategy(ac);
}
return str;
}
/*
/******************************************************
/* Property auto-detection
/******************************************************
*/
@Override
public VisibilityChecker<?> findAutoDetectVisibility(AnnotatedClass ac,
VisibilityChecker<?> checker)
{
/* Note: to have proper priorities, we must actually call delegatees
* in reverse order:
*/
checker = _secondary.findAutoDetectVisibility(ac, checker);
return _primary.findAutoDetectVisibility(ac, checker);
}
/*
/******************************************************
/* Type handling
/******************************************************
*/
@Override
public TypeResolverBuilder<?> findTypeResolver(MapperConfig<?> config,
AnnotatedClass ac, JavaType baseType)
{
TypeResolverBuilder<?> b = _primary.findTypeResolver(config, ac, baseType);
if (b == null) {
b = _secondary.findTypeResolver(config, ac, baseType);
}
return b;
}
@Override
public TypeResolverBuilder<?> findPropertyTypeResolver(MapperConfig<?> config,
AnnotatedMember am, JavaType baseType)
{
TypeResolverBuilder<?> b = _primary.findPropertyTypeResolver(config, am, baseType);
if (b == null) {
b = _
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> SimpleType(cls);
}
@Override
public SimpleType withTypeHandler(Object h)
{
return new SimpleType(_class, _typeNames, _typeParameters, _valueHandler, h, _asStatic);
}
@Override
public JavaType withContentTypeHandler(Object h) {
// no content type, so:
throw new IllegalArgumentException("Simple types have no content types; can not call withContenTypeHandler()");
}
@Override
public SimpleType withValueHandler(Object h) {
if (h == _valueHandler) {
return this;
}
return new SimpleType(_class, _typeNames, _typeParameters, h, _typeHandler, _asStatic);
}
@Override
public SimpleType withContentValueHandler(Object h) {
// no content type, so:
throw new IllegalArgumentException("Simple types have no content types; can not call withContenValueHandler()");
}
@Override
public SimpleType withStaticTyping() {
return _asStatic ? this : new SimpleType(_class,
_typeNames, _typeParameters, _valueHandler, _typeHandler, _asStatic);
}
@Override
protected String buildCanonicalName()
{
StringBuilder sb = new StringBuilder();
sb.append(_class.getName());
if (_typeParameters != null && _typeParameters.length > 0) {
sb.append('<');
boolean first = true;
for (JavaType t : _typeParameters) {
if (first) {
first = false;
} else {
sb.append(',');
}
sb.append(t.toCanonical());
}
sb.append('>');
}
return sb.toString();
}
/*
/**********************************************************
/* Public API
/**********************************************************
*/
@Override
public boolean isContainerType() { return false; }
@Override
public int containedTypeCount() {
return (_typeParameters == null) ? 0 : _typeParameters.length;
}
@Override
public JavaType containedType(int index)
{
if (index < 0 || _typeParameters == null || index >= _typeParameters.length) {
return null;
}
return _typeParameters[index];
}
@Override
public String containedTypeName(int index)
{
if (index < 0 || _typeNames == null || index >= _typeNames.length) {
return null;
}
return _typeNames[index];
}
@Override
public StringBuilder getErasedSignature(StringBuilder sb) {
return _classSignature(_class, sb, true);
}
@Override
public StringBuilder getGenericSignature(StringBuilder sb)
{
_classSignature(_class, sb, false);
if (_typeParameters != null) {
sb.append('<');
for (JavaType param : _typeParameters) {
sb = param.getGenericSignature(sb);
}
sb.append('>');
}
sb.append(';');
return sb;
}
/*
/**********************************************************
/* Standard methods
/**********************************************************
*/
@Override
public String toString()
{
StringBuilder sb = new StringBuilder(40);
sb.append("[simple type, class ").append(buildCanonicalName()).append(']');
return sb.toString();
}
@Override
public boolean equals(Object o)
{
if (
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> use PropertyName for implicit names too
pn = _propNameFromSimple(implName);
nameExplicit = false;
}
visible = true;
}
boolean ignore = (ai == null) ? false : ai.hasIgnoreMarker(m);
_property(implName).addGetter(m, pn, nameExplicit, visible, ignore);
}
protected void _addSetterMethod(AnnotatedMethod m, AnnotationIntrospector ai)
{
String implName; // from naming convention
boolean visible;
PropertyName pn = (ai == null) ? null : ai.findNameForDeserialization(m);
boolean nameExplicit = (pn != null);
if (!nameExplicit) { // no explicit name; must follow naming convention
implName = (ai == null) ? null : ai.findImplicitPropertyName(m);
if (implName == null) {
implName = BeanUtil.okNameForMutator(m, _mutatorPrefix);
}
if (implName == null) { // if not, must skip
return;
}
visible = _visibilityChecker.isSetterVisible(m);
} else { // explicit indication of inclusion, but may be empty
// we still need implicit name to link with other pieces
implName = (ai == null) ? null : ai.findImplicitPropertyName(m);
if (implName == null) {
implName = BeanUtil.okNameForMutator(m, _mutatorPrefix);
}
// if not regular getter name, use method name as is
if (implName == null) {
implName = m.getName();
}
if (pn.isEmpty()) {
// !!! TODO: use PropertyName for implicit names too
pn = _propNameFromSimple(implName);
nameExplicit = false;
}
visible = true;
}
boolean ignore = (ai == null) ? false : ai.hasIgnoreMarker(m);
_property(implName).addSetter(m, pn, nameExplicit, visible, ignore);
}
protected void _addInjectables()
{
final AnnotationIntrospector ai = _annotationIntrospector;
if (ai == null) {
return;
}
// first fields, then methods
for (AnnotatedField f : _classDef.fields()) {
_doAddInjectable(ai.findInjectableValueId(f), f);
}
for (AnnotatedMethod m : _classDef.memberMethods()) {
/* for now, only allow injection of a single arg
* (to be changed in future)
*/
if (m.getParameterCount() != 1) {
continue;
}
_doAddInjectable(ai.findInjectableValueId(m), m);
}
}
protected void _doAddInjectable(Object id, AnnotatedMember m)
{
if (id == null) {
return;
}
if (_injectables == null) {
_injectables = new LinkedHashMap<Object, AnnotatedMember>();
}
AnnotatedMember prev = _injectables.put(id, m);
if (prev != null) {
String type = id.getClass().getName();
throw new IllegalArgumentException("Duplicate injectable value with id '"
+String.valueOf(id)+"' (of type "+type+")");
}
}
private PropertyName _propNameFromSimple(String simpleName) {
return PropertyName
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.impl;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.util.ClassUtil;
/**
* This sub-class is used to handle special case of value being a
* non-static inner class. If so, we will have to use a special
* alternative for default constructor; but otherwise can delegate
* to regular implementation.
*/
public final class InnerClassProperty
extends SettableBeanProperty
{
private static final long serialVersionUID = 1L;
/**
* Actual property that we use after value construction.
*/
protected final SettableBeanProperty _delegate;
/**
* Single-arg constructor we use for value instantiation.
*/
protected final Constructor<?> _creator;
public InnerClassProperty(SettableBeanProperty delegate,
Constructor<?> ctor)
{
super(delegate);
_delegate = delegate;
_creator = ctor;
}
protected InnerClassProperty(InnerClassProperty src, JsonDeserializer<?> deser)
{
super(src, deser);
_delegate = src._delegate.withValueDeserializer(deser);
_creator = src._creator;
}
protected InnerClassProperty(InnerClassProperty src, PropertyName newName) {
super(src, newName);
_delegate = src._delegate.withName(newName);
_creator = src._creator;
}
@Override
public InnerClassProperty withName(PropertyName newName) {
return new InnerClassProperty(this, newName);
}
@Override
public InnerClassProperty withValueDeserializer(JsonDeserializer<?> deser) {
return new InnerClassProperty(this, deser);
}
// // // BeanProperty impl
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return _delegate.getAnnotation(acls);
}
@Override public AnnotatedMember getMember() { return _delegate.getMember(); }
/*
/**********************************************************
/* Deserialization methods
/**********************************************************
*/
@Override
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt,
Object bean)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
Object value;
if (t == JsonToken.VALUE_NULL) {
value = (_nullProvider == null) ? null : _nullProvider.nullValue(ctxt);
} else if (_valueTypeDeserializer != null) {
value = _valueDeserializer.deserializeWithType(jp, ctxt, _valueTypeDeserializer);
} else { // the usual case
try {
value = _creator.newInstance(bean);
} catch (Exception e) {
ClassUtil.unwrapAndThrowAsIAE(e, "Failed to instantiate class "+_creator.getDeclaringClass().getName
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
@JacksonStdImpl
public final class StringDeserializer extends StdScalarDeserializer<String>
{
private static final long serialVersionUID = 1L;
/**
* @since 2.2
*/
public final static StringDeserializer instance = new StringDeserializer();
public StringDeserializer() { super(String.class); }
@Override
public String deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
JsonToken curr = jp.getCurrentToken();
if (curr == JsonToken.VALUE_STRING) {
return jp.getText();
}
// Issue#381
if (curr == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final String parsed = _parseString(jp, ctxt);
if (jp.nextToken() != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'String' value but there was more than a single value in the array");
}
return parsed;
}
// [JACKSON-330]: need to gracefully handle byte[] data, as base64
if (curr == JsonToken.VALUE_EMBEDDED_OBJECT) {
Object ob = jp.getEmbeddedObject();
if (ob == null) {
return null;
}
if (ob instanceof byte[]) {
return Base64Variants.getDefaultVariant().encode((byte[]) ob, false);
}
// otherwise, try conversion using toString()...
return ob.toString();
}
// allow coercions for other scalar types
String text = jp.getValueAsString();
if (text != null) {
return text;
}
throw ctxt.mappingException(_valueClass, curr);
}
// 1.6: since we can never have type info ("natural type"; String, Boolean, Integer, Double):
// (is it an error to even call this version?)
@Override
public String deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
return deserialize(jp, ctxt);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> protected transient HierarchicType _cachedArrayListType;
/*
/**********************************************************
/* Configuration
/**********************************************************
*/
/**
* Registered {@link TypeModifier}s: objects that can change details
* of {@link JavaType} instances factory constructs.
*/
protected final TypeModifier[] _modifiers;
protected final TypeParser _parser;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
private TypeFactory() {
_parser = new TypeParser(this);
_modifiers = null;
}
protected TypeFactory(TypeParser p, TypeModifier[] mods) {
_parser = p;
_modifiers = mods;
}
public TypeFactory withModifier(TypeModifier mod)
{
if (mod == null) { // mostly for unit tests
return new TypeFactory(_parser, _modifiers);
}
if (_modifiers == null) {
return new TypeFactory(_parser, new TypeModifier[] { mod });
}
return new TypeFactory(_parser, ArrayBuilders.insertInListNoDup(_modifiers, mod));
}
/**
* Method used to access the globally shared instance, which has
* no custom configuration. Used by <code>ObjectMapper</code> to
* get the default factory when constructed.
*/
public static TypeFactory defaultInstance() { return instance; }
/**
* Method that will clear up any cached type definitions that may
* be cached by this {@link TypeFactory} instance.
* This method should not be commonly used, that is, only use it
* if you know there is a problem with retention of type definitions;
* the most likely (and currently only known) problem is retention
* of {@link Class} instances via {@link JavaType} reference.
*
* @since 2.4.1
*/
public void clearCache() {
_typeCache.clear();
}
/*
/**********************************************************
/* Static methods for non-instance-specific functionality
/**********************************************************
*/
/**
* Method for constructing a marker type that indicates missing generic
* type information, which is handled same as simple type for
* <code>java.lang.Object</code>.
*/
public static JavaType unknownType() {
return defaultInstance()._unknownType();
}
/**
* Static helper method that can be called to figure out type-erased
* call for given JDK type. It can be called statically since type resolution
* process can never change actual type-erased class; thereby static
* default instance is used for determination.
*/
public static Class<?> rawClass(Type t) {
if (t instanceof Class<?>) {
return (Class<?>) t;
}
// Shouldbe able to optimize bit more in future...
return defaultInstance().constructType(t).getRawClass();
}
/*
/**********************************************************
/* Type conversion, parameterization resolution methods
/**********************************************************
*/
/**
* Factory method for creating a subtype of given base type, as defined
* by specified subclass; but retaining generic type information if any.
* Can be used, for example, to get equivalent of "HashMap<String,Integer>"
* from "Map<String,Integer>" by giving <code>HashMap.class</code>
* as subclass.
*/
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass)
{
//
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>T extends X<T>>)
if (parents != null) {
for (Type parent : parents) {
HierarchicType sup = _findSuperInterfaceChain(parent, target);
if (sup != null) {
sup.setSubType(current);
current.setSuperType(sup);
return current;
}
}
}
// and then super-class if any
Type parent = raw.getGenericSuperclass();
if (parent != null) {
HierarchicType sup = _findSuperInterfaceChain(parent, target);
if (sup != null) {
sup.setSubType(current);
current.setSuperType(sup);
return current;
}
}
return null;
}
protected synchronized HierarchicType _hashMapSuperInterfaceChain(HierarchicType current)
{
if (_cachedHashMapType == null) {
HierarchicType base = current.deepCloneWithoutSubtype();
_doFindSuperInterfaceChain(base, Map.class);
_cachedHashMapType = base.getSuperType();
}
HierarchicType t = _cachedHashMapType.deepCloneWithoutSubtype();
current.setSuperType(t);
t.setSubType(current);
return current;
}
protected synchronized HierarchicType _arrayListSuperInterfaceChain(HierarchicType current)
{
if (_cachedArrayListType == null) {
HierarchicType base = current.deepCloneWithoutSubtype();
_doFindSuperInterfaceChain(base, List.class);
_cachedArrayListType = base.getSuperType();
}
HierarchicType t = _cachedArrayListType.deepCloneWithoutSubtype();
current.setSuperType(t);
t.setSubType(current);
return current;
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> rawPropertyType = getter.getRawType();
if (Collection.class.isAssignableFrom(rawPropertyType)
|| Map.class.isAssignableFrom(rawPropertyType)) {
prop = constructSetterlessProperty(ctxt, beanDesc, propDef);
}
}
if (propDef.hasConstructorParameter()) {
/* [JACKSON-700] If property is passed via constructor parameter, we must
* handle things in special way. Not sure what is the most optimal way...
* for now, let's just call a (new) method in builder, which does nothing.
*/
// but let's call a method just to allow custom builders to be aware...
final String name = propDef.getName();
CreatorProperty cprop = null;
if (creatorProps != null) {
for (SettableBeanProperty cp : creatorProps) {
if (name.equals(cp.getName())) {
cprop = (CreatorProperty) cp;
break;
}
}
}
if (cprop == null) {
throw ctxt.mappingException("Could not find creator property with name '"
+name+"' (in class "+beanDesc.getBeanClass().getName()+")");
}
if (prop != null) {
cprop = cprop.withFallbackSetter(prop);
}
prop = cprop;
builder.addCreatorProperty(cprop);
continue;
}
if (prop != null) {
Class<?>[] views = propDef.findViews();
if (views == null) {
// one more twist: if default inclusion disabled, need to force empty set of views
if (!ctxt.isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION)) {
views = NO_VIEWS;
}
}
// one more thing before adding to builder: copy any metadata
prop.setViews(views);
builder.addProperty(prop);
}
}
}
/**
* Helper method called to filter out explicit ignored properties,
* as well as properties that have "ignorable types".
* Note that this will not remove properties that have no
* setters.
*/
protected List<BeanPropertyDefinition> filterBeanProps(DeserializationContext ctxt,
BeanDescription beanDesc, BeanDeserializerBuilder builder,
List<BeanPropertyDefinition> propDefsIn,
Set<String> ignored)
throws JsonMappingException
{
ArrayList<BeanPropertyDefinition> result = new ArrayList<BeanPropertyDefinition>(
Math.max(4, propDefsIn.size()));
HashMap<Class<?>,Boolean> ignoredTypes = new HashMap<Class<?>,Boolean>();
// These are all valid setters, but we do need to introspect bit more
for (BeanPropertyDefinition property : propDefsIn) {
String name = property.getName();
if (ignored.contains(name)) { // explicit ignoral using @JsonIgnoreProperties needs to block entries
continue;
}
if (!property.hasConstructorParameter()) { // never skip constructor params
Class<?> rawPropertyType = null;
if (property.hasSetter()) {
rawPropertyType = property.getSetter().getRawParameterType(0);
} else if (property.hasField()) {
rawPropertyType = property.getField().getRawType();
}
// [JACKSON-429] Some types are declared as ignorable as well
if ((rawPropertyType != null)
&& (isIgnorableType(ctxt.getConfig
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> specified
// [JACKSON-163]
wrap = _config.isEnabled(SerializationFeature.WRAP_ROOT_VALUE);
if (wrap) {
PropertyName pname = _rootNames.findRootName(value.getClass(), _config);
jgen.writeStartObject();
jgen.writeFieldName(pname.simpleAsEncoded(_config));
}
} else if (rootName.length() == 0) {
wrap = false;
} else { // [JACKSON-764]
// empty String means explicitly disabled; non-empty that it is enabled
wrap = true;
jgen.writeStartObject();
jgen.writeFieldName(rootName);
}
try {
ser.serialize(value, jgen, this);
if (wrap) {
jgen.writeEndObject();
}
} catch (IOException ioe) { // As per [JACKSON-99], pass IOException and subtypes as-is
throw ioe;
} catch (Exception e) { // but wrap RuntimeExceptions, to get path information
String msg = e.getMessage();
if (msg == null) {
msg = "[no message for "+e.getClass().getName()+"]";
}
throw new JsonMappingException(msg, e);
}
}
/**
* The method to be called by {@link ObjectMapper} and {@link ObjectWriter}
* for serializing given value (assumed to be of specified root type,
* instead of runtime type of value),
* using serializers that
* this provider has access to (via caching and/or creating new serializers
* as need be),
*
* @param rootType Type to use for locating serializer to use, instead of actual
* runtime type. Must be actual type, or one of its super types
*/
public void serializeValue(JsonGenerator jgen, Object value, JavaType rootType) throws IOException
{
if (value == null) {
_serializeNull(jgen);
return;
}
// Let's ensure types are compatible at this point
if (!rootType.getRawClass().isAssignableFrom(value.getClass())) {
_reportIncompatibleRootType(value, rootType);
}
// root value, not reached via property:
JsonSerializer<Object> ser = findTypedValueSerializer(rootType, true, null);
// Ok: should we wrap result in an additional property ("root name")?
final boolean wrap;
String rootName = _config.getRootName();
if (rootName == null) { // not explicitly specified
// [JACKSON-163]
wrap = _config.isEnabled(SerializationFeature.WRAP_ROOT_VALUE);
if (wrap) {
jgen.writeStartObject();
PropertyName pname = _rootNames.findRootName(value.getClass(), _config);
jgen.writeFieldName(pname.simpleAsEncoded(_config));
}
} else if (rootName.length() == 0) {
wrap = false;
} else { // [JACKSON-764]
// empty String means explicitly disabled; non-empty that it is enabled
wrap = true;
jgen.writeStartObject();
jgen.writeFieldName(rootName);
}
try {
ser.serialize(value, jgen, this);
if (wrap) {
jgen.
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>writeEndObject();
}
} catch (IOException ioe) { // no wrapping for IO (and derived)
throw ioe;
} catch (Exception e) { // but others do need to be, to get path etc
String msg = e.getMessage();
if (msg == null) {
msg = "[no message for "+e.getClass().getName()+"]";
}
throw new JsonMappingException(msg, e);
}
}
/**
* The method to be called by {@link ObjectWriter}
* for serializing given value (assumed to be of specified root type,
* instead of runtime type of value), when it may know specific
* {@link JsonSerializer} to use.
*
* @param rootType Type to use for locating serializer to use, instead of actual
* runtime type, if no serializer is passed
* @param ser Root Serializer to use, if not null
*
* @since 2.1
*/
public void serializeValue(JsonGenerator jgen, Object value, JavaType rootType, JsonSerializer<Object> ser) throws IOException
{
if (value == null) {
_serializeNull(jgen);
return;
}
// Let's ensure types are compatible at this point
if ((rootType != null) && !rootType.getRawClass().isAssignableFrom(value.getClass())) {
_reportIncompatibleRootType(value, rootType);
}
// root value, not reached via property:
if (ser == null) {
ser = findTypedValueSerializer(rootType, true, null);
}
// Ok: should we wrap result in an additional property ("root name")?
final boolean wrap;
String rootName = _config.getRootName();
if (rootName == null) { // not explicitly specified
// [JACKSON-163]
wrap = _config.isEnabled(SerializationFeature.WRAP_ROOT_VALUE);
if (wrap) {
jgen.writeStartObject();
PropertyName pname = (rootType == null)
? _rootNames.findRootName(value.getClass(), _config)
: _rootNames.findRootName(rootType, _config);
jgen.writeFieldName(pname.simpleAsEncoded(_config));
}
} else if (rootName.length() == 0) {
wrap = false;
} else { // [JACKSON-764]
// empty String means explicitly disabled; non-empty that it is enabled
wrap = true;
jgen.writeStartObject();
jgen.writeFieldName(rootName);
}
try {
ser.serialize(value, jgen, this);
if (wrap) {
jgen.writeEndObject();
}
} catch (IOException ioe) { // no wrapping for IO (and derived)
throw ioe;
} catch (Exception e) { // but others do need to be, to get path etc
String msg = e.getMessage();
if (msg == null) {
msg = "[no message for "+e.getClass().getName()+"]";
}
throw new JsonMappingException(msg, e);
}
}
/**
* Helper method called when root value to serialize is null
*
* @since 2.3
*/
protected void _serializeNull(JsonGenerator jgen) throws IOException
{
JsonSerializer<Object>
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> be called to check whether a default creator (constructor,
* or no-arg static factory method)
* is available for this instantiator
*/
public boolean canCreateUsingDefault() { return getDefaultCreator() != null; }
/**
* Method that can be called to check whether a delegate-based creator (single-arg
* constructor or factory method)
* is available for this instantiator
*/
public boolean canCreateUsingDelegate() { return false; }
/**
* Method that can be called to check whether a property-based creator
* (argument-taking constructor or factory method)
* is available to instantiate values from JSON Object
*/
public boolean canCreateFromObjectWith() { return false; }
/**
* Method called to determine types of instantiation arguments
* to use when creating instances with creator arguments
* (when {@link #canCreateFromObjectWith()} returns true).
* These arguments are bound from JSON, using specified
* property types to locate deserializers.
*<p>
* NOTE: all properties will be of type
* {@link com.fasterxml.jackson.databind.deser.CreatorProperty}.
*/
public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) { return null; }
/**
* Method that can be used to determine what is the type of delegate
* type to use, if any; if no delegates are used, will return null.
* If non-null type is returned, deserializer will bind JSON into
* specified type (using standard deserializer for that type), and
* pass that to instantiator.
*/
public JavaType getDelegateType(DeserializationConfig config) { return null; }
/*
/**********************************************************
/* Instantiation methods for JSON Object
/**********************************************************
*/
/**
* Method called to create value instance from a JSON value when
* no data needs to passed to creator (constructor, factory method);
* typically this will call the default constructor of the value object.
* It will only be used if more specific creator methods are not
* applicable; hence "default".
*<p>
* This method is called if {@link #getFromObjectArguments} returns
* null or empty List.
*/
public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
throw ctxt.mappingException("Can not instantiate value of type "
+getValueTypeDesc()+"; no default creator found");
}
/**
* Method called to create value instance from JSON Object when
* instantiation arguments are passed; this is done, for example when passing information
* specified with "Creator" annotations.
*<p>
* This method is called if {@link #getFromObjectArguments} returns
* a non-empty List of arguments.
*/
public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) throws IOException {
throw ctxt.mappingException("Can not instantiate value of type "+getValueTypeDesc()+" with arguments");
}
/**
* Method to called to create value instance from JSON Object using
* an intermediate "delegate" value to pass to createor method
*/
public Object createUsingDelegate(DeserializationContext ctxt, Object delegate) throws IOException {
throw ctxt.mappingException("Can not instantiate value of type "+getValueTypeDesc()+" using delegate");
}
/*
/**********************************************************
/* Instantiation methods for JSON scalar types
/* (String, Number, Boolean)
/**********************************************************
*/
public
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> Object createFromString(DeserializationContext ctxt, String value) throws IOException {
return _createFromStringFallbacks(ctxt, value);
}
public Object createFromInt(DeserializationContext ctxt, int value) throws IOException {
throw ctxt.mappingException("Can not instantiate value of type "
+getValueTypeDesc()+" from Integer number ("+value+", int)");
}
public Object createFromLong(DeserializationContext ctxt, long value) throws IOException {
throw ctxt.mappingException("Can not instantiate value of type "
+getValueTypeDesc()+" from Integer number ("+value+", long)");
}
public Object createFromDouble(DeserializationContext ctxt, double value) throws IOException {
throw ctxt.mappingException("Can not instantiate value of type "
+getValueTypeDesc()+" from Floating-point number ("+value+", double)");
}
public Object createFromBoolean(DeserializationContext ctxt, boolean value) throws IOException {
throw ctxt.mappingException("Can not instantiate value of type "
+getValueTypeDesc()+" from Boolean value ("+value+")");
}
/*
/**********************************************************
/* Accessors for underlying creator objects (optional)
/**********************************************************
*/
/**
* Method that can be called to try to access member (constructor,
* static factory method) that is used as the "default creator"
* (creator that is called without arguments; typically default
* [zero-argument] constructor of the type).
* Note that implementations not required to return actual object
* they use (or, they may use some other instantiation) method.
* That is, even if {@link #canCreateUsingDefault()} returns true,
* this method may return null .
*/
public AnnotatedWithParams getDefaultCreator() { return null; }
/**
* Method that can be called to try to access member (constructor,
* static factory method) that is used as the "delegate creator".
* Note that implementations not required to return actual object
* they use (or, they may use some other instantiation) method.
* That is, even if {@link #canCreateUsingDelegate()} returns true,
* this method may return null .
*/
public AnnotatedWithParams getDelegateCreator() { return null; }
/**
* Method that can be called to try to access member (constructor,
* static factory method) that is used as the "non-default creator"
* (constructor or factory method that takes one or more arguments).
* Note that implementations not required to return actual object
* they use (or, they may use some other instantiation) method.
* That is, even if {@link #canCreateFromObjectWith()} returns true,
* this method may return null .
*/
public AnnotatedWithParams getWithArgsCreator() { return null; }
/**
* If an incomplete creator was found, this is the first parameter that
* needs further annotation to help make the creator complete.
*/
public AnnotatedParameter getIncompleteParameter() { return null; }
/*
/**********************************************************
/* Helper methods
/**********************************************************
*/
/**
* @since 2.4 (demoted from <code>StdValueInstantiator)
*/
protected Object _createFromStringFallbacks(DeserializationContext ctxt, String value)
throws IOException, JsonProcessingException
{
/* 28-Sep-2011, tatu: Ok this is not clean at all; but since there are legacy
* systems that expect conversions in
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> some cases, let's just add a minimal
* patch (note: same could conceivably be used for numbers too).
*/
if (canCreateFromBoolean()) {
String str = value.trim();
if ("true".equals(str)) {
return createFromBoolean(ctxt, true);
}
if ("false".equals(str)) {
return createFromBoolean(ctxt, false);
}
}
// also, empty Strings might be accepted as null Object...
if (value.length() == 0) {
if (ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) {
return null;
}
}
throw ctxt.mappingException("Can not instantiate value of type "+getValueTypeDesc()
+" from String value ('"+value+"'); no single-String constructor/factory method");
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
/**
* Standard deserializer for {@link EnumSet}s.
* <p>
* Note: casting within this class is all messed up -- just could not figure out a way
* to properly deal with recursive definition of "EnumSet<K extends Enum<K>, V>
*/
@SuppressWarnings("rawtypes")
public class EnumSetDeserializer
extends StdDeserializer<EnumSet<?>>
implements ContextualDeserializer
{
private static final long serialVersionUID = 3479455075597887177L;
protected final JavaType _enumType;
protected final Class<Enum> _enumClass;
protected JsonDeserializer<Enum<?>> _enumDeserializer;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
@SuppressWarnings("unchecked" )
public EnumSetDeserializer(JavaType enumType, JsonDeserializer<?> deser)
{
super(EnumSet.class);
_enumType = enumType;
_enumClass = (Class<Enum>) enumType.getRawClass();
_enumDeserializer = (JsonDeserializer<Enum<?>>) deser;
}
public EnumSetDeserializer withDeserializer(JsonDeserializer<?> deser) {
if (_enumDeserializer == deser) {
return this;
}
return new EnumSetDeserializer(_enumType, deser);
}
/**
* Because of costs associated with constructing Enum resolvers,
* let's cache instances by default.
*/
@Override
public boolean isCachable() { return true; }
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
BeanProperty property) throws JsonMappingException
{
JsonDeserializer<?> deser = _enumDeserializer;
if (deser == null) {
deser = ctxt.findContextualValueDeserializer(_enumType, property);
} else { // if directly assigned, probably not yet contextual, so:
deser = ctxt.handleSecondaryContextualization(deser, property);
}
return withDeserializer(deser);
}
/*
/**********************************************************
/* JsonDeserializer API
/**********************************************************
*/
@SuppressWarnings("unchecked")
@Override
public EnumSet<?> deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// Ok: must point to START_ARRAY (or equivalent)
if (!jp.isExpectedStartArrayToken()) {
throw ctxt.mappingException(EnumSet.class);
}
EnumSet result = constructSet();
JsonToken t;
try {
while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
/* What to do with nulls? Fail or ignore? Fail, for now
* (note: would fail if we passed it to EnumDeserializer, too,
* but in general nulls should never be passed to non-container
* deserializers)
*/
if (t == JsonToken.VALUE_NULL) {
throw ctxt.mappingException(_enumClass);
}
Enum<?> value = _enumDeserializer.deserialize(jp, ctxt);
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>(SerializationConfig config,
BeanDescription beanDesc, TypeSerializer typeSer)
{
/* 16-Aug-2010, tatu: If there is a (value) type serializer, we can not force
* static typing; that would make it impossible to handle expected subtypes
*/
if (typeSer != null) {
return false;
}
AnnotationIntrospector intr = config.getAnnotationIntrospector();
JsonSerialize.Typing t = intr.findSerializationTyping(beanDesc.getClassInfo());
if (t != null && t != JsonSerialize.Typing.DEFAULT_TYPING) {
return (t == JsonSerialize.Typing.STATIC);
}
return config.isEnabled(MapperFeature.USE_STATIC_TYPING);
}
protected Class<?> _verifyAsClass(Object src, String methodName, Class<?> noneClass)
{
if (src == null) {
return null;
}
if (!(src instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector."+methodName+"() returned value of type "+src.getClass().getName()+": expected type JsonSerializer or Class<JsonSerializer> instead");
}
Class<?> cls = (Class<?>) src;
if (cls == noneClass || ClassUtil.isBogusClass(cls)) {
return null;
}
return cls;
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>getName();
/* [Issue-13]: Need to consider Injectables, which may not have
* a name at all, and need to be skipped
*/
if (name.length() == 0 && properties[i].getInjectableValueId() != null) {
continue;
}
Integer old = names.put(name, Integer.valueOf(i));
if (old != null) {
throw new IllegalArgumentException("Duplicate creator property \""+name+"\" (index "+old+" vs "+i+")");
}
}
}
_propertyBasedArgs = properties;
}
public void addIncompeteParameter(AnnotatedParameter parameter) {
if (_incompleteParameter == null) {
_incompleteParameter = parameter;
}
}
/*
/**********************************************************
/* Accessors
/**********************************************************
*/
/**
* @since 2.1
*/
public boolean hasDefaultCreator() {
return _defaultConstructor != null;
}
/*
/**********************************************************
/* Helper methods
/**********************************************************
*/
private <T extends AnnotatedMember> T _fixAccess(T member)
{
if (member != null && _canFixAccess) {
ClassUtil.checkAndFixAccess((Member) member.getAnnotated());
}
return member;
}
protected AnnotatedWithParams verifyNonDup(AnnotatedWithParams newOne, AnnotatedWithParams oldOne,
String type)
{
if (oldOne != null) {
// important: ok to override factory with constructor; but not within same type, so:
if (oldOne.getClass() == newOne.getClass()) {
throw new IllegalArgumentException("Conflicting "+type+" creators: already had "+oldOne+", encountered "+newOne);
}
}
return _fixAccess(newOne);
}
/*
/**********************************************************
/* Helper class(es)
/**********************************************************
*/
protected final static class Vanilla
extends ValueInstantiator
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
public final static int TYPE_COLLECTION = 1;
public final static int TYPE_MAP = 2;
public final static int TYPE_HASH_MAP = 3;
private final int _type;
public Vanilla(int t) {
_type = t;
}
@Override
public String getValueTypeDesc() {
switch (_type) {
case TYPE_COLLECTION: return ArrayList.class.getName();
case TYPE_MAP: return LinkedHashMap.class.getName();
case TYPE_HASH_MAP: return HashMap.class.getName();
}
return Object.class.getName();
}
@Override
public boolean canInstantiate() { return true; }
@Override
public boolean canCreateUsingDefault() { return true; }
@Override
public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
switch (_type) {
case TYPE_COLLECTION: return new ArrayList<Object>();
case TYPE_MAP: return new LinkedHashMap<String,Object>();
case TYPE_HASH_MAP: return new HashMap<String,Object>();
}
throw new IllegalStateException("Unknown type "+_type);
}
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import java.util.Arrays;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* Value node that contains Base64 encoded binary value, which will be
* output and stored as Json String value.
*/
public class BinaryNode
extends ValueNode
{
final static BinaryNode EMPTY_BINARY_NODE = new BinaryNode(new byte[0]);
protected final byte[] _data;
public BinaryNode(byte[] data)
{
_data = data;
}
public BinaryNode(byte[] data, int offset, int length)
{
if (offset == 0 && length == data.length) {
_data = data;
} else {
_data = new byte[length];
System.arraycopy(data, offset, _data, 0, length);
}
}
public static BinaryNode valueOf(byte[] data)
{
if (data == null) {
return null;
}
if (data.length == 0) {
return EMPTY_BINARY_NODE;
}
return new BinaryNode(data);
}
public static BinaryNode valueOf(byte[] data, int offset, int length)
{
if (data == null) {
return null;
}
if (length == 0) {
return EMPTY_BINARY_NODE;
}
return new BinaryNode(data, offset, length);
}
@Override
public JsonNodeType getNodeType()
{
return JsonNodeType.BINARY;
}
@Override
public JsonToken asToken() {
/* No distinct type; could use one for textual values,
* but given that it's not in text form at this point,
* embedded-object is closest
*/
return JsonToken.VALUE_EMBEDDED_OBJECT;
}
/**
*<p>
* Note: caller is not to modify returned array in any way, since
* it is not a copy but reference to the underlying byte array.
*/
@Override
public byte[] binaryValue() { return _data; }
/**
* Hmmh. This is not quite as efficient as using {@link #serialize},
* but will work correctly.
*/
@Override
public String asText() {
return Base64Variants.getDefaultVariant().encode(_data, false);
}
@Override
public final void serialize(JsonGenerator jg, SerializerProvider provider)
throws IOException, JsonProcessingException
{
jg.writeBinary(provider.getConfig().getBase64Variant(),
_data, 0, _data.length);
}
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof BinaryNode)) {
return false;
}
return Arrays.equals(((BinaryNode) o)._data, _data);
}
@Override
public int hashCode() {
return (_data == null) ? -1 : _data.length;
}
/**
* Different from other values, since contents need to be surrounded
* by (double) quotes.
*/
@Override
public String toString()
{
return Base64Variants.getDefaultVariant().encode(_data, true);
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>.0
*/
public JsonSerializer<?> getKeySerializer() {
return _keySerializer;
}
/*
/**********************************************************
/* JsonSerializer implementation
/**********************************************************
*/
@Override
public void serialize(Map<?,?> value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
jgen.writeStartObject();
if (!value.isEmpty()) {
if (_filterId != null) {
serializeFilteredFields(value, jgen, provider,
findPropertyFilter(provider, _filterId, value));
jgen.writeEndObject();
return;
}
if (_sortKeys || provider.isEnabled(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS)) {
value = _orderEntries(value);
}
if (_valueSerializer != null) {
serializeFieldsUsing(value, jgen, provider, _valueSerializer);
} else {
serializeFields(value, jgen, provider);
}
}
jgen.writeEndObject();
}
@Override
public void serializeWithType(Map<?,?> value, JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer)
throws IOException, JsonGenerationException
{
typeSer.writeTypePrefixForObject(value, jgen);
if (!value.isEmpty()) {
if (_sortKeys || provider.isEnabled(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS)) {
value = _orderEntries(value);
}
if (_valueSerializer != null) {
serializeFieldsUsing(value, jgen, provider, _valueSerializer);
} else {
serializeFields(value, jgen, provider);
}
}
typeSer.writeTypeSuffixForObject(value, jgen);
}
/*
/**********************************************************
/* JsonSerializer implementation
/**********************************************************
*/
/**
* Method called to serialize fields, when the value type is not statically known.
*/
public void serializeFields(Map<?,?> value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
// If value type needs polymorphic type handling, some more work needed:
if (_valueTypeSerializer != null) {
serializeTypedFields(value, jgen, provider);
return;
}
final JsonSerializer<Object> keySerializer = _keySerializer;
final HashSet<String> ignored = _ignoredEntries;
final boolean skipNulls = !provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES);
PropertySerializerMap serializers = _dynamicValueSerializers;
for (Map.Entry<?,?> entry : value.entrySet()) {
Object valueElem = entry.getValue();
// First, serialize key
Object keyElem = entry.getKey();
if (keyElem == null) {
provider.findNullKeySerializer(_keyType, _property).serialize(null, jgen, provider);
} else {
// [JACKSON-314] skip entries with null values?
if (skipNulls && valueElem == null) continue;
// One twist: is entry ignorable? If so, skip
if (ignored != null && ignored.contains(keyElem)) continue;
keySerializer.serialize(keyElem, jgen, provider);
}
// And then value
if (valueElem == null) {
provider.defaultSerializeNull(jgen);
} else {
Class<?> cc = valueElem.getClass
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>(JsonParser jp, DeserializationContext ctxt) throws IOException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_TRUE) return true;
if (t == JsonToken.VALUE_FALSE) return false;
if (t == JsonToken.VALUE_NULL) return false;
// [JACKSON-78]: should accept ints too, (0 == false, otherwise true)
if (t == JsonToken.VALUE_NUMBER_INT) {
// 11-Jan-2012, tatus: May be outside of int...
if (jp.getNumberType() == NumberType.INT) {
return (jp.getIntValue() != 0);
}
return _parseBooleanFromNumber(jp, ctxt);
}
// And finally, let's allow Strings to be converted too
if (t == JsonToken.VALUE_STRING) {
String text = jp.getText().trim();
// [#422]: Allow aliases
if ("true".equals(text) || "True".equals(text)) {
return true;
}
if ("false".equals(text) || "False".equals(text) || text.length() == 0) {
return false;
}
if (_hasTextualNull(text)) {
return false;
}
throw ctxt.weirdStringException(text, _valueClass, "only \"true\" or \"false\" recognized");
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final boolean parsed = _parseBooleanPrimitive(jp, ctxt);
t = jp.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'boolean' value but there was more than a single value in the array");
}
return parsed;
}
// Otherwise, no can do:
throw ctxt.mappingException(_valueClass, t);
}
protected final Boolean _parseBoolean(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_TRUE) {
return Boolean.TRUE;
}
if (t == JsonToken.VALUE_FALSE) {
return Boolean.FALSE;
}
// [JACKSON-78]: should accept ints too, (0 == false, otherwise true)
if (t == JsonToken.VALUE_NUMBER_INT) {
// 11-Jan-2012, tatus: May be outside of int...
if (jp.getNumberType() == NumberType.INT) {
return (jp.getIntValue() == 0) ? Boolean.FALSE : Boolean.TRUE;
}
return Boolean.valueOf(_parseBooleanFromNumber(jp, ctxt));
}
if (t == JsonToken.VALUE_NULL) {
return (Boolean) getNullValue();
}
// And finally, let's allow Strings to be converted too
if (t == JsonToken.VALUE_STRING) {
String text = jp.getText().trim();
// [#422]: Allow aliases
if ("true".equals(text) ||
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> "True".equals(text)) {
return Boolean.TRUE;
}
if ("false".equals(text) || "False".equals(text)) {
return Boolean.FALSE;
}
if (text.length() == 0) {
return (Boolean) getEmptyValue();
}
if (_hasTextualNull(text)) {
return (Boolean) getNullValue();
}
throw ctxt.weirdStringException(text, _valueClass, "only \"true\" or \"false\" recognized");
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final Boolean parsed = _parseBoolean(jp, ctxt);
t = jp.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'Boolean' value but there was more than a single value in the array");
}
return parsed;
}
// Otherwise, no can do:
throw ctxt.mappingException(_valueClass, t);
}
protected final boolean _parseBooleanFromNumber(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
if (jp.getNumberType() == NumberType.LONG) {
return (jp.getLongValue() == 0L) ? Boolean.FALSE : Boolean.TRUE;
}
// no really good logic; let's actually resort to textual comparison
String str = jp.getText();
if ("0.0".equals(str) || "0".equals(str)) {
return Boolean.FALSE;
}
return Boolean.TRUE;
}
protected Byte _parseByte(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
return jp.getByteValue();
}
if (t == JsonToken.VALUE_STRING) { // let's do implicit re-parse
String text = jp.getText().trim();
if (_hasTextualNull(text)) {
return (Byte) getNullValue();
}
int value;
try {
int len = text.length();
if (len == 0) {
return (Byte) getEmptyValue();
}
value = NumberInput.parseInt(text);
} catch (IllegalArgumentException iae) {
throw ctxt.weirdStringException(text, _valueClass, "not a valid Byte value");
}
// So far so good: but does it fit?
// as per [JACKSON-804], allow range up to 255, inclusive
if (value < Byte.MIN_VALUE || value > 255) {
throw ctxt.weirdStringException(text, _valueClass, "overflow, value can not be represented as 8-bit value");
}
return Byte.valueOf((byte) value);
}
if (t == JsonToken.VALUE_NULL) {
return (Byte) getNullValue();
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final Byte parsed = _parseByte(jp, ctxt);
t = jp.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'Byte' value but there was more than a single value in the array");
}
return parsed;
}
throw ctxt.mappingException(_valueClass, t);
}
protected Short _parseShort(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
return jp.getShortValue();
}
if (t == JsonToken.VALUE_STRING) { // let's do implicit re-parse
String text = jp.getText().trim();
int value;
try {
int len = text.length();
if (len == 0) {
return (Short) getEmptyValue();
}
if (_hasTextualNull(text)) {
return (Short) getNullValue();
}
value = NumberInput.parseInt(text);
} catch (IllegalArgumentException iae) {
throw ctxt.weirdStringException(text, _valueClass, "not a valid Short value");
}
// So far so good: but does it fit?
if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
throw ctxt.weirdStringException(text, _valueClass, "overflow, value can not be represented as 16-bit value");
}
return Short.valueOf((short) value);
}
if (t == JsonToken.VALUE_NULL) {
return (Short) getNullValue();
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final Short parsed = _parseShort(jp, ctxt);
t = jp.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'Short' value but there was more than a single value in the array");
}
return parsed;
}
throw ctxt.mappingException(_valueClass, t);
}
protected final short _parseShortPrimitive(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
int value = _parseIntPrimitive(jp, ctxt);
// So far so good: but does it fit?
if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
throw ctxt.weirdStringException(String.valueOf(value),
_valueClass, "overflow, value can not be represented as 16-bit value");
}
return (short) value;
}
protected final int _parseIntPrimitive(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
JsonToken t = jp.getCurrentToken();
// Int works as is, coercing fine as well
if (t == JsonToken.VALUE_NUMBER_INT || t ==
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
return jp.getIntValue();
}
if (t == JsonToken.VALUE_STRING) { // let's do implicit re-parse
String text = jp.getText().trim();
if (_hasTextualNull(text)) {
return 0;
}
try {
int len = text.length();
if (len > 9) {
long l = Long.parseLong(text);
if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
throw ctxt.weirdStringException(text, _valueClass,
"Overflow: numeric value ("+text+") out of range of int ("+Integer.MIN_VALUE+" - "+Integer.MAX_VALUE+")");
}
return (int) l;
}
if (len == 0) {
return 0;
}
return NumberInput.parseInt(text);
} catch (IllegalArgumentException iae) {
throw ctxt.weirdStringException(text, _valueClass, "not a valid int value");
}
}
if (t == JsonToken.VALUE_NULL) {
return 0;
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final int parsed = _parseIntPrimitive(jp, ctxt);
t = jp.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'int' value but there was more than a single value in the array");
}
return parsed;
}
// Otherwise, no can do:
throw ctxt.mappingException(_valueClass, t);
}
protected final Integer _parseInteger(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
return Integer.valueOf(jp.getIntValue());
}
if (t == JsonToken.VALUE_STRING) { // let's do implicit re-parse
String text = jp.getText().trim();
try {
int len = text.length();
if (_hasTextualNull(text)) {
return (Integer) getNullValue();
}
if (len > 9) {
long l = Long.parseLong(text);
if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
throw ctxt.weirdStringException(text, _valueClass,
"Overflow: numeric value ("+text+") out of range of Integer ("+Integer.MIN_VALUE+" - "+Integer.MAX_VALUE+")");
}
return Integer.valueOf((int) l);
}
if (len == 0) {
return (Integer) getEmptyValue();
}
return Integer.valueOf(NumberInput.parseInt(text));
} catch (IllegalArgumentException iae) {
throw ctxt.weirdStringException(text, _valueClass, "not a valid Integer value");
}
}
if (t == JsonToken.VALUE_NULL) {
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
return (Integer) getNullValue();
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final Integer parsed = _parseInteger(jp, ctxt);
t = jp.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'Integer' value but there was more than a single value in the array");
}
return parsed;
}
// Otherwise, no can do:
throw ctxt.mappingException(_valueClass, t);
}
protected final Long _parseLong(JsonParser jp, DeserializationContext ctxt) throws IOException
{
JsonToken t = jp.getCurrentToken();
// it should be ok to coerce (although may fail, too)
if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) {
return jp.getLongValue();
}
// let's allow Strings to be converted too
if (t == JsonToken.VALUE_STRING) {
// !!! 05-Jan-2009, tatu: Should we try to limit value space, JDK is too lenient?
String text = jp.getText().trim();
if (text.length() == 0) {
return (Long) getEmptyValue();
}
if (_hasTextualNull(text)) {
return (Long) getNullValue();
}
try {
return Long.valueOf(NumberInput.parseLong(text));
} catch (IllegalArgumentException iae) { }
throw ctxt.weirdStringException(text, _valueClass, "not a valid Long value");
}
if (t == JsonToken.VALUE_NULL) {
return (Long) getNullValue();
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final Long parsed = _parseLong(jp, ctxt);
t = jp.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'Long' value but there was more than a single value in the array");
}
return parsed;
}
// Otherwise, no can do:
throw ctxt.mappingException(_valueClass, t);
}
protected final long _parseLongPrimitive(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) {
return jp.getLongValue();
}
if (t == JsonToken.VALUE_STRING) {
String text = jp.getText().trim();
if (text.length() == 0 || _hasTextualNull(text)) {
return 0L;
}
try {
return NumberInput.parseLong(text);
} catch (IllegalArgumentException iae) { }
throw ctxt.weirdStringException(text, _valueClass, "not a valid long
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> value");
}
if (t == JsonToken.VALUE_NULL) {
return 0L;
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final long parsed = _parseLongPrimitive(jp, ctxt);
t = jp.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'long' value but there was more than a single value in the array");
}
return parsed;
}
throw ctxt.mappingException(_valueClass, t);
}
protected final Float _parseFloat(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
// We accept couple of different types; obvious ones first:
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
return jp.getFloatValue();
}
// And finally, let's allow Strings to be converted too
if (t == JsonToken.VALUE_STRING) {
String text = jp.getText().trim();
if (text.length() == 0) {
return (Float) getEmptyValue();
}
if (_hasTextualNull(text)) {
return (Float) getNullValue();
}
switch (text.charAt(0)) {
case 'I':
if (_isPosInf(text)) {
return Float.POSITIVE_INFINITY;
}
break;
case 'N':
if (_isNaN(text)) {
return Float.NaN;
}
break;
case '-':
if (_isNegInf(text)) {
return Float.NEGATIVE_INFINITY;
}
break;
}
try {
return Float.parseFloat(text);
} catch (IllegalArgumentException iae) { }
throw ctxt.weirdStringException(text, _valueClass, "not a valid Float value");
}
if (t == JsonToken.VALUE_NULL) {
return (Float) getNullValue();
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final Float parsed = _parseFloat(jp, ctxt);
t = jp.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'Byte' value but there was more than a single value in the array");
}
return parsed;
}
// Otherwise, no can do:
throw ctxt.mappingException(_valueClass, t);
}
protected final float _parseFloatPrimitive(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
return jp.getFloatValue();
}
if (t == JsonToken.VALUE_STRING) {
String text = jp.
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>getText().trim();
if (text.length() == 0 || _hasTextualNull(text)) {
return 0.0f;
}
switch (text.charAt(0)) {
case 'I':
if (_isPosInf(text)) {
return Float.POSITIVE_INFINITY;
}
break;
case 'N':
if (_isNaN(text)) { return Float.NaN; }
break;
case '-':
if (_isNegInf(text)) {
return Float.NEGATIVE_INFINITY;
}
break;
}
try {
return Float.parseFloat(text);
} catch (IllegalArgumentException iae) { }
throw ctxt.weirdStringException(text, _valueClass, "not a valid float value");
}
if (t == JsonToken.VALUE_NULL) {
return 0.0f;
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final float parsed = _parseFloatPrimitive(jp, ctxt);
t = jp.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'float' value but there was more than a single value in the array");
}
return parsed;
}
// Otherwise, no can do:
throw ctxt.mappingException(_valueClass, t);
}
protected final Double _parseDouble(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
return jp.getDoubleValue();
}
if (t == JsonToken.VALUE_STRING) {
String text = jp.getText().trim();
if (text.length() == 0) {
return (Double) getEmptyValue();
}
if (_hasTextualNull(text)) {
return (Double) getNullValue();
}
switch (text.charAt(0)) {
case 'I':
if (_isPosInf(text)) {
return Double.POSITIVE_INFINITY;
}
break;
case 'N':
if (_isNaN(text)) {
return Double.NaN;
}
break;
case '-':
if (_isNegInf(text)) {
return Double.NEGATIVE_INFINITY;
}
break;
}
try {
return parseDouble(text);
} catch (IllegalArgumentException iae) { }
throw ctxt.weirdStringException(text, _valueClass, "not a valid Double value");
}
if (t == JsonToken.VALUE_NULL) {
return (Double) getNullValue();
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final Double parsed = _parseDouble(jp, ctxt);
t = jp.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> value array for single 'Double' value but there was more than a single value in the array");
}
return parsed;
}
// Otherwise, no can do:
throw ctxt.mappingException(_valueClass, t);
}
protected final double _parseDoublePrimitive(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
// We accept couple of different types; obvious ones first:
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
return jp.getDoubleValue();
}
// And finally, let's allow Strings to be converted too
if (t == JsonToken.VALUE_STRING) {
String text = jp.getText().trim();
if (text.length() == 0 || _hasTextualNull(text)) {
return 0.0;
}
switch (text.charAt(0)) {
case 'I':
if (_isPosInf(text)) {
return Double.POSITIVE_INFINITY;
}
break;
case 'N':
if (_isNaN(text)) {
return Double.NaN;
}
break;
case '-':
if (_isNegInf(text)) {
return Double.NEGATIVE_INFINITY;
}
break;
}
try {
return parseDouble(text);
} catch (IllegalArgumentException iae) { }
throw ctxt.weirdStringException(text, _valueClass, "not a valid double value");
}
if (t == JsonToken.VALUE_NULL) {
return 0.0;
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final double parsed = _parseDoublePrimitive(jp, ctxt);
t = jp.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'Byte' value but there was more than a single value in the array");
}
return parsed;
}
// Otherwise, no can do:
throw ctxt.mappingException(_valueClass, t);
}
protected java.util.Date _parseDate(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT) {
return new java.util.Date(jp.getLongValue());
}
if (t == JsonToken.VALUE_NULL) {
return (java.util.Date) getNullValue();
}
if (t == JsonToken.VALUE_STRING) {
String value = null;
try {
// As per [JACKSON-203], take empty Strings to mean
value = jp.getText().trim();
if (value.length() == 0) {
return (Date) getEmptyValue();
}
if (_hasTextualNull(value)) {
return (java.util.Date) getNullValue();
}
return ctxt.parseDate(value);
} catch (IllegalArgumentException iae) {
throw ctxt.weirdStringException(value, _valueClass,
"not a
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> valid representation (error: "+iae.getMessage()+")");
}
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final Date parsed = _parseDate(jp, ctxt);
t = jp.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'java.util.Date' value but there was more than a single value in the array");
}
return parsed;
}
throw ctxt.mappingException(_valueClass, t);
}
/**
* Helper method for encapsulating calls to low-level double value parsing; single place
* just because we need a work-around that must be applied to all calls.
*/
protected final static double parseDouble(String numStr) throws NumberFormatException
{
// [JACKSON-486]: avoid some nasty float representations... but should it be MIN_NORMAL or MIN_VALUE?
// for now, MIN_VALUE, since MIN_NORMAL is JDK 1.6
if (NumberInput.NASTY_SMALL_DOUBLE.equals(numStr)) {
return Double.MIN_VALUE;
}
return Double.parseDouble(numStr);
}
/**
* Helper method used for accessing String value, if possible, doing
* necessary conversion or throwing exception as necessary.
*
* @since 2.1
*/
protected final String _parseString(JsonParser jp, DeserializationContext ctxt) throws IOException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_STRING) {
return jp.getText();
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final String parsed = _parseString(jp, ctxt);
if (jp.nextToken() != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'String' value but there was more than a single value in the array");
}
return parsed;
}
String value = jp.getValueAsString();
if (value != null) {
return value;
}
throw ctxt.mappingException(String.class, jp.getCurrentToken());
}
/**
* Helper method called to determine if we are seeing String value of
* "null", and, further, that it should be coerced to null just like
* null token.
*
* @since 2.3
*/
protected boolean _hasTextualNull(String value) {
return "null".equals(value);
}
protected final boolean _isNegInf(String text) {
return "-Infinity".equals(text) || "-INF".equals(text);
}
protected final boolean _isPosInf(String text) {
return "Infinity".equals(text) || "INF".equals(text);
}
protected final boolean _isNaN(String text) { return "NaN".equals(text); }
/*
/****************************************************
/* Helper methods for sub
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.util.ObjectBuffer;
/**
* Separate implementation for serializing String arrays (instead of
* using {@link ObjectArrayDeserializer}.
* Used if (and only if) no custom value deserializers are used.
*/
@JacksonStdImpl
public final class StringArrayDeserializer
extends StdDeserializer<String[]>
implements ContextualDeserializer
{
private static final long serialVersionUID = -7589512013334920693L;
public final static StringArrayDeserializer instance = new StringArrayDeserializer();
/**
* Value serializer to use, if not the standard one (which is inlined)
*/
protected JsonDeserializer<String> _elementDeserializer;
public StringArrayDeserializer() {
super(String[].class);
_elementDeserializer = null;
}
@SuppressWarnings("unchecked")
protected StringArrayDeserializer(JsonDeserializer<?> deser) {
super(String[].class);
_elementDeserializer = (JsonDeserializer<String>) deser;
}
@Override
public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
// Ok: must point to START_ARRAY (or equivalent)
if (!jp.isExpectedStartArrayToken()) {
return handleNonArray(jp, ctxt);
}
if (_elementDeserializer != null) {
return _deserializeCustom(jp, ctxt);
}
final ObjectBuffer buffer = ctxt.leaseObjectBuffer();
Object[] chunk = buffer.resetAndStart();
int ix = 0;
JsonToken t;
try {
while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
// Ok: no need to convert Strings, but must recognize nulls
String value;
if (t == JsonToken.VALUE_STRING) {
value = jp.getText();
} else if (t == JsonToken.VALUE_NULL) {
value = null; // since we have established that '_elementDeserializer == null' earlier
} else {
value = _parseString(jp, ctxt);
}
if (ix >= chunk.length) {
chunk = buffer.appendCompletedChunk(chunk);
ix = 0;
}
chunk[ix++] = value;
}
} catch (Exception e) {
throw JsonMappingException.wrapWithPath(e, chunk, ix);
}
String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class);
ctxt.returnObjectBuffer(buffer);
return result;
}
/**
* Offlined version used when we do not use the default deserialization method.
*/
protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException
{
final ObjectBuffer buffer = ctxt.leaseObjectBuffer();
Object[] chunk = buffer.resetAndStart();
final JsonDeserializer<String> deser = _elementDeserializer;
int ix = 0;
JsonToken t;
try {
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
// Ok: no need to convert Strings, but must recognize nulls
String value = (t == JsonToken.VALUE_NULL) ? deser.getNullValue() : deser.deserialize(jp, ctxt);
if (ix >= chunk.length) {
chunk = buffer.appendCompletedChunk(chunk);
ix = 0;
}
chunk[ix++] = value;
}
} catch (Exception e) {
// note: pass String.class, not String[].class, as we need element type for error info
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class);
ctxt.returnObjectBuffer(buffer);
return result;
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
return typeDeserializer.deserializeTypedFromArray(jp, ctxt);
}
private final String[] handleNonArray(JsonParser jp, DeserializationContext ctxt) throws IOException
{
// [JACKSON-526]: implicit arrays from single values?
if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)) {
// [JACKSON-620] Empty String can become null...
if ((jp.getCurrentToken() == JsonToken.VALUE_STRING)
&& ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) {
String str = jp.getText();
if (str.length() == 0) {
return null;
}
}
throw ctxt.mappingException(_valueClass);
}
return new String[] { (jp.getCurrentToken() == JsonToken.VALUE_NULL) ? null : _parseString(jp, ctxt) };
}
/**
* Contextualization is needed to see whether we can "inline" deserialization
* of String values, or if we have to use separate value deserializer.
*/
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException
{
JsonDeserializer<?> deser = _elementDeserializer;
// #125: May have a content converter
deser = findConvertingContentDeserializer(ctxt, property, deser);
if (deser == null) {
deser = ctxt.findContextualValueDeserializer(ctxt.constructType(String.class), property);
} else { // if directly assigned, probably not yet contextual, so:
deser = ctxt.handleSecondaryContextualization(deser, property);
}
// Ok ok: if all we got is the default String deserializer, can just forget about it
if (deser != null && this.isDefaultDeserializer(deser)) {
deser = null;
}
if (_elementDeserializer != deser) {
return new StringArrayDeserializer(deser);
}
return this;
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.type;
import java.lang.reflect.*;
import java.util.*;
import com.fasterxml.jackson.databind.JavaType;
/**
* Helper class used for resolving type parameters for given class
*/
public class TypeBindings
{
private final static JavaType[] NO_TYPES = new JavaType[0];
/**
* Marker to use for (temporarily) unbound references.
*/
public final static JavaType UNBOUND = new SimpleType(Object.class);
/**
* Factory to use for constructing resolved related types.
*/
protected final TypeFactory _typeFactory;
/**
* Context type used for resolving all types, if specified. May be null,
* in which case {@link #_contextClass} is used instead.
*/
protected final JavaType _contextType;
/**
* Specific class to use for resolving all types, for methods and fields
* class and its superclasses and -interfaces contain.
*/
protected final Class<?> _contextClass;
/**
* Lazily-instantiated bindings of resolved type parameters
*/
protected Map<String,JavaType> _bindings;
/**
* Also: we may temporarily want to mark certain named types
* as resolved (but without exact type); if so, we'll just store
* names here.
*/
protected HashSet<String> _placeholders;
/**
* Sometimes it is necessary to allow hierarchic resolution of types: specifically
* in cases where there are local bindings (for methods, constructors). If so,
* we'll just use simple delegation model.
*/
private final TypeBindings _parentBindings;
/*
/**********************************************************
/* Construction
/**********************************************************
*/
public TypeBindings(TypeFactory typeFactory, Class<?> cc)
{
this(typeFactory, null, cc, null);
}
public TypeBindings(TypeFactory typeFactory, JavaType type)
{
this(typeFactory, null, type.getRawClass(), type);
}
/**
* Constructor used to create "child" instances; mostly to
* allow delegation from explicitly defined local overrides
* (local type variables for methods, constructors) to
* contextual (class-defined) ones.
*/
public TypeBindings childInstance() {
return new TypeBindings(_typeFactory, this, _contextClass, _contextType);
}
private TypeBindings(TypeFactory tf, TypeBindings parent,
Class<?> cc, JavaType type)
{
_typeFactory = tf;
_parentBindings = parent;
_contextClass = cc;
_contextType = type;
}
/*
/**********************************************************
/* Pass-through type resolution methods
/**********************************************************
*/
public JavaType resolveType(Class<?> cls) {
return _typeFactory._constructType(cls, this);
}
public JavaType resolveType(Type type) {
return _typeFactory._constructType(type, this);
}
/*
/**********************************************************
/* Accesors
/**********************************************************
*/
public int getBindingCount() {
if (_bindings == null) {
_resolve();
}
return _bindings.size();
}
public JavaType findType(String name)
{
if (_bindings == null) {
_resolve();
}
JavaType t = _bindings.get(name);
if (t != null
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>) {
return t;
}
if (_placeholders != null && _placeholders.contains(name)) {
return UNBOUND;
}
if (_parentBindings != null) {
return _parentBindings.findType(name);
}
// nothing found, so...
// Should we throw an exception or just return null?
/* [JACKSON-499] 18-Feb-2011, tatu: There are some tricky type bindings within
* java.util, such as HashMap$KeySet; so let's punt the problem
* (honestly not sure what to do -- they are unbound for good, I think)
*/
if (_contextClass != null) {
Class<?> enclosing = _contextClass.getEnclosingClass();
if (enclosing != null) {
// [JACKSON-572]: Actually, let's skip this for all non-static inner classes
// (which will also cover 'java.util' type cases...
if (!Modifier.isStatic(_contextClass.getModifiers())) {
return UNBOUND;
}
// ... so this piece of code should not be needed any more
/*
Package pkg = enclosing.getPackage();
if (pkg != null) {
// as per [JACKSON-533], also include "java.util.concurrent":
if (pkg.getName().startsWith("java.util")) {
return UNBOUND;
}
}
*/
}
}
String className;
if (_contextClass != null) {
className = _contextClass.getName();
} else if (_contextType != null) {
className = _contextType.toString();
} else {
className = "UNKNOWN";
}
throw new IllegalArgumentException("Type variable '"+name
+"' can not be resolved (with context of class "+className+")");
//t = UNBOUND;
}
public void addBinding(String name, JavaType type)
{
// note: emptyMap() is unmodifiable, hence second check is needed:
if (_bindings == null || _bindings.size() == 0) {
_bindings = new LinkedHashMap<String,JavaType>();
}
_bindings.put(name, type);
}
public JavaType[] typesAsArray()
{
if (_bindings == null) {
_resolve();
}
if (_bindings.size() == 0) {
return NO_TYPES;
}
return _bindings.values().toArray(new JavaType[_bindings.size()]);
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
protected void _resolve()
{
_resolveBindings(_contextClass);
// finally: may have root level type info too
if (_contextType != null) {
int count = _contextType.containedTypeCount();
if (count > 0) {
for (int i = 0; i < count; ++i) {
String name = _contextType.containedTypeName(i);
JavaType type = _contextType.containedType(i);
addBinding(name, type);
}
}
}
// nothing bound? mark with empty map to prevent further calls
if (_bindings == null) {
_bindings = Collections.emptyMap();
}
}
public void _addPlaceholder(String name) {
if
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> (_placeholders == null) {
_placeholders = new HashSet<String>();
}
_placeholders.add(name);
}
protected void _resolveBindings(Type t)
{
if (t == null) return;
Class<?> raw;
if (t instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) t;
Type[] args = pt.getActualTypeArguments();
if (args != null && args.length > 0) {
Class<?> rawType = (Class<?>) pt.getRawType();
TypeVariable<?>[] vars = rawType.getTypeParameters();
if (vars.length != args.length) {
throw new IllegalArgumentException("Strange parametrized type (in class "+rawType.getName()+"): number of type arguments != number of type parameters ("+args.length+" vs "+vars.length+")");
}
for (int i = 0, len = args.length; i < len; ++i) {
TypeVariable<?> var = vars[i];
String name = var.getName();
if (_bindings == null) {
_bindings = new LinkedHashMap<String,JavaType>();
} else {
/* 24-Mar-2010, tatu: Better ensure that we do not overwrite something
* collected earlier (since we descend towards super-classes):
*/
if (_bindings.containsKey(name)) continue;
}
// first: add a placeholder to prevent infinite loops
_addPlaceholder(name);
// then resolve type
_bindings.put(name, _typeFactory._constructType(args[i], this));
}
}
raw = (Class<?>)pt.getRawType();
} else if (t instanceof Class<?>) {
raw = (Class<?>) t;
/* [JACKSON-677]: If this is an inner class then the generics are defined on the
* enclosing class so we have to check there as well. We don't
* need to call getEnclosingClass since anonymous classes declare
* generics
*/
Class<?> decl = raw.getDeclaringClass();
/* 08-Feb-2013, tatu: Except that if context is also super-class, we must
* skip it; context will be checked anyway, and we'd get StackOverflow if
* we went there.
*/
if (decl != null && !decl.isAssignableFrom(raw)) {
_resolveBindings(raw.getDeclaringClass());
}
/* 24-Mar-2010, tatu: Can not have true generics definitions, but can
* have lower bounds ("<T extends BeanBase>") in declaration itself
*/
TypeVariable<?>[] vars = raw.getTypeParameters();
if (vars != null && vars.length > 0) {
JavaType[] typeParams = null;
if (_contextType != null && raw.isAssignableFrom(_contextType.getRawClass())) {
typeParams = _typeFactory.findTypeParameters(_contextType, raw);
}
for (int i = 0; i < vars.length; i++) {
TypeVariable<?> var = vars[i];
String name = var.getName();
Type varType = var.getBounds()[0];
if (varType != null) {
if (_bindings == null) {
_bindings = new LinkedHashMap<
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* This singleton value class is used to contain explicit JSON null
* value.
*/
public final class NullNode
extends ValueNode
{
// // Just need a fly-weight singleton
public final static NullNode instance = new NullNode();
private NullNode() { }
public static NullNode getInstance() { return instance; }
@Override
public JsonNodeType getNodeType()
{
return JsonNodeType.NULL;
}
@Override public JsonToken asToken() { return JsonToken.VALUE_NULL; }
@Override public String asText(String defaultValue) { return defaultValue; }
@Override public String asText() { return "null"; }
// as with MissingNode, not considered number node; hence defaults are returned if provided
/*
public int asInt(int defaultValue);
public long asLong(long defaultValue);
public double asDouble(double defaultValue);
public boolean asBoolean(boolean defaultValue);
*/
@Override
public final void serialize(JsonGenerator jg, SerializerProvider provider)
throws IOException, JsonProcessingException
{
provider.defaultSerializeNull(jg);
}
@Override
public boolean equals(Object o)
{
return (o == this);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> = findDeserializer(ctxt, delegateType, property);
}
}
JsonDeserializer<?> valueDeser = _valueDeserializer;
if (valueDeser == null) {
// #125: May have a content converter
valueDeser = findConvertingContentDeserializer(ctxt, property, valueDeser);
if (valueDeser == null) {
// And we may also need to get deserializer for String
valueDeser = ctxt.findContextualValueDeserializer( _collectionType.getContentType(), property);
}
} else { // if directly assigned, probably not yet contextual, so:
valueDeser = ctxt.handleSecondaryContextualization(valueDeser, property);
}
if (isDefaultDeserializer(valueDeser)) {
valueDeser = null;
}
return withResolved(delegate, valueDeser);
}
/*
/**********************************************************
/* ContainerDeserializerBase API
/**********************************************************
*/
@Override
public JavaType getContentType() {
return _collectionType.getContentType();
}
@SuppressWarnings("unchecked")
@Override
public JsonDeserializer<Object> getContentDeserializer() {
JsonDeserializer<?> deser = _valueDeserializer;
return (JsonDeserializer<Object>) deser;
}
/*
/**********************************************************
/* JsonDeserializer API
/**********************************************************
*/
@SuppressWarnings("unchecked")
@Override
public Collection<String> deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException
{
if (_delegateDeserializer != null) {
return (Collection<String>) _valueInstantiator.createUsingDelegate(ctxt,
_delegateDeserializer.deserialize(jp, ctxt));
}
final Collection<String> result = (Collection<String>) _valueInstantiator.createUsingDefault(ctxt);
return deserialize(jp, ctxt, result);
}
@Override
public Collection<String> deserialize(JsonParser jp, DeserializationContext ctxt,
Collection<String> result)
throws IOException
{
// Ok: must point to START_ARRAY
if (!jp.isExpectedStartArrayToken()) {
return handleNonArray(jp, ctxt, result);
}
if (_valueDeserializer != null) {
return deserializeUsingCustom(jp, ctxt, result, _valueDeserializer);
}
JsonToken t;
try {
while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
String value;
if (t == JsonToken.VALUE_STRING) {
value = jp.getText();
} else if (t == JsonToken.VALUE_NULL) {
value = null;
} else {
value = _parseString(jp, ctxt);
}
result.add(value);
}
} catch (Exception e) {
throw JsonMappingException.wrapWithPath(e, result, result.size());
}
return result;
}
private Collection<String> deserializeUsingCustom(JsonParser jp, DeserializationContext ctxt,
Collection<String> result, final JsonDeserializer<String> deser) throws IOException
{
JsonToken t;
while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
String value;
if (t == JsonToken.VALUE_NULL) {
value = deser.getNullValue();
} else {
value = deser.deserialize(jp, ctxt);
}
result.add(value);
}
return result;
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> @Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
// In future could check current token... for now this should be enough:
return typeDeserializer.deserializeTypedFromArray(jp, ctxt);
}
/**
* Helper method called when current token is no START_ARRAY. Will either
* throw an exception, or try to handle value as if member of implicit
* array, depending on configuration.
*/
private final Collection<String> handleNonArray(JsonParser jp, DeserializationContext ctxt, Collection<String> result) throws IOException
{
// [JACKSON-526]: implicit arrays from single values?
if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)) {
throw ctxt.mappingException(_collectionType.getRawClass());
}
// Strings are one of "native" (intrinsic) types, so there's never type deserializer involved
JsonDeserializer<String> valueDes = _valueDeserializer;
JsonToken t = jp.getCurrentToken();
String value;
if (t == JsonToken.VALUE_NULL) {
value = (valueDes == null) ? null : valueDes.getNullValue();
} else {
value = (valueDes == null) ? _parseString(jp, ctxt) : valueDes.deserialize(jp, ctxt);
}
result.add(value);
return result;
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.io.NumberOutput;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* Numeric node that contains simple 32-bit integer values.
*/
public class IntNode
extends NumericNode
{
// // // Let's cache small set of common value
final static int MIN_CANONICAL = -1;
final static int MAX_CANONICAL = 10;
private final static IntNode[] CANONICALS;
static {
int count = MAX_CANONICAL - MIN_CANONICAL + 1;
CANONICALS = new IntNode[count];
for (int i = 0; i < count; ++i) {
CANONICALS[i] = new IntNode(MIN_CANONICAL + i);
}
}
/**
* Integer value this node contains
*/
protected final int _value;
/*
************************************************
* Construction
************************************************
*/
public IntNode(int v) { _value = v; }
public static IntNode valueOf(int i) {
if (i > MAX_CANONICAL || i < MIN_CANONICAL) return new IntNode(i);
return CANONICALS[i - MIN_CANONICAL];
}
/*
/**********************************************************
/* BaseJsonNode extended API
/**********************************************************
*/
@Override public JsonToken asToken() { return JsonToken.VALUE_NUMBER_INT; }
@Override
public JsonParser.NumberType numberType() { return JsonParser.NumberType.INT; }
/*
/**********************************************************
/* Overrridden JsonNode methods
/**********************************************************
*/
@Override
public boolean isIntegralNumber() { return true; }
@Override
public boolean isInt() { return true; }
@Override public boolean canConvertToInt() { return true; }
@Override public boolean canConvertToLong() { return true; }
@Override
public Number numberValue() {
return Integer.valueOf(_value);
}
@Override
public short shortValue() { return (short) _value; }
@Override
public int intValue() { return _value; }
@Override
public long longValue() { return (long) _value; }
@Override
public float floatValue() { return (float) _value; }
@Override
public double doubleValue() { return (double) _value; }
@Override
public BigDecimal decimalValue() { return BigDecimal.valueOf(_value); }
@Override
public BigInteger bigIntegerValue() { return BigInteger.valueOf(_value); }
@Override
public String asText() {
return NumberOutput.toString(_value);
}
@Override
public boolean asBoolean(boolean defaultValue) {
return _value != 0;
}
@Override
public final void serialize(JsonGenerator jg, SerializerProvider provider)
throws IOException, JsonProcessingException
{
jg.writeNumber(_value);
}
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o instanceof
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> {
serializeFieldsFiltered(bean, jgen, provider);
} else {
serializeFields(bean, jgen, provider);
}
if (typeStr == null) {
typeSer.writeTypeSuffixForObject(bean, jgen);
} else {
typeSer.writeCustomTypeSuffixForObject(bean, jgen, typeStr);
}
}
protected final void _serializeWithObjectId(Object bean,
JsonGenerator jgen, SerializerProvider provider,
boolean startEndObject)
throws IOException, JsonGenerationException
{
final ObjectIdWriter w = _objectIdWriter;
WritableObjectId objectId = provider.findObjectId(bean, w.generator);
// If possible, write as id already
if (objectId.writeAsId(jgen, provider, w)) {
return;
}
// If not, need to inject the id:
Object id = objectId.generateId(bean);
if (w.alwaysAsId) {
w.serializer.serialize(id, jgen, provider);
return;
}
if (startEndObject) {
jgen.writeStartObject();
}
objectId.writeAsField(jgen, provider, w);
if (_propertyFilterId != null) {
serializeFieldsFiltered(bean, jgen, provider);
} else {
serializeFields(bean, jgen, provider);
}
if (startEndObject) {
jgen.writeEndObject();
}
}
protected final void _serializeWithObjectId(Object bean,
JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer)
throws IOException, JsonGenerationException
{
final ObjectIdWriter w = _objectIdWriter;
WritableObjectId objectId = provider.findObjectId(bean, w.generator);
// If possible, write as id already
if (objectId.writeAsId(jgen, provider, w)) {
return;
}
// If not, need to inject the id:
Object id = objectId.generateId(bean);
if (w.alwaysAsId) {
w.serializer.serialize(id, jgen, provider);
return;
}
_serializeObjectId(bean, jgen, provider, typeSer, objectId);
}
protected void _serializeObjectId(Object bean,
JsonGenerator jgen,SerializerProvider provider,
TypeSerializer typeSer, WritableObjectId objectId)
throws IOException, JsonProcessingException, JsonGenerationException {
final ObjectIdWriter w = _objectIdWriter;
String typeStr = (_typeId == null) ? null :_customTypeId(bean);
if (typeStr == null) {
typeSer.writeTypePrefixForObject(bean, jgen);
} else {
typeSer.writeCustomTypePrefixForObject(bean, jgen, typeStr);
}
objectId.writeAsField(jgen, provider, w);
if (_propertyFilterId != null) {
serializeFieldsFiltered(bean, jgen, provider);
} else {
serializeFields(bean, jgen, provider);
}
if (typeStr == null) {
typeSer.writeTypeSuffixForObject(bean, jgen);
} else {
typeSer.writeCustomTypeSuffixForObject(bean, jgen, typeStr);
}
}
private final String _customTypeId(Object bean)
{
final Object typeId = _
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> == props.length) ? "[anySetter]" : props[i].getName();
wrapAndThrow(provider, e, bean, name);
} catch (StackOverflowError e) {
JsonMappingException mapE = new JsonMappingException("Infinite recursion (StackOverflowError)", e);
String name = (i == props.length) ? "[anySetter]" : props[i].getName();
mapE.prependPath(new JsonMappingException.Reference(bean, name));
throw mapE;
}
}
@Deprecated
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
throws JsonMappingException
{
ObjectNode o = createSchemaNode("object", true);
// [JACKSON-813]: Add optional JSON Schema id attribute, if found
// NOTE: not optimal, does NOT go through AnnotationIntrospector etc:
JsonSerializableSchema ann = _handledType.getAnnotation(JsonSerializableSchema.class);
if (ann != null) {
String id = ann.id();
if (id != null && id.length() > 0) {
o.put("id", id);
}
}
//todo: should the classname go in the title?
//o.put("title", _className);
ObjectNode propertiesNode = o.objectNode();
final PropertyFilter filter;
if (_propertyFilterId != null) {
filter = findPropertyFilter(provider, _propertyFilterId, null);
} else {
filter = null;
}
for (int i = 0; i < _props.length; i++) {
BeanPropertyWriter prop = _props[i];
if (filter == null) {
prop.depositSchemaProperty(propertiesNode, provider);
} else {
filter.depositSchemaProperty(prop, propertiesNode, provider);
}
}
o.put("properties", propertiesNode);
return o;
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
//deposit your output format
if (visitor == null) {
return;
}
JsonObjectFormatVisitor objectVisitor = visitor.expectObjectFormat(typeHint);
if (objectVisitor == null) {
return;
}
if (_propertyFilterId != null) {
PropertyFilter filter = findPropertyFilter(visitor.getProvider(),
_propertyFilterId, null);
for (int i = 0; i < _props.length; i++) {
filter.depositSchemaProperty(_props[i], objectVisitor, visitor.getProvider());
}
} else {
for (int i = 0; i < _props.length; i++) {
_props[i].depositSchemaProperty(objectVisitor);
}
}
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.io.NumberOutput;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* Numeric node that contains simple 64-bit integer values.
*/
public class LongNode
extends NumericNode
{
protected final long _value;
/*
************************************************
* Construction
************************************************
*/
public LongNode(long v) { _value = v; }
public static LongNode valueOf(long l) { return new LongNode(l); }
/*
************************************************
* Overrridden JsonNode methods
************************************************
*/
@Override public JsonToken asToken() { return JsonToken.VALUE_NUMBER_INT; }
@Override
public JsonParser.NumberType numberType() { return JsonParser.NumberType.LONG; }
@Override
public boolean isIntegralNumber() { return true; }
@Override
public boolean isLong() { return true; }
@Override public boolean canConvertToInt() {
return (_value >= Integer.MIN_VALUE && _value <= Integer.MAX_VALUE);
}
@Override public boolean canConvertToLong() { return true; }
@Override
public Number numberValue() {
return Long.valueOf(_value);
}
@Override
public short shortValue() { return (short) _value; }
@Override
public int intValue() { return (int) _value; }
@Override
public long longValue() { return _value; }
@Override
public float floatValue() { return _value; }
@Override
public double doubleValue() { return _value; }
@Override
public BigDecimal decimalValue() { return BigDecimal.valueOf(_value); }
@Override
public BigInteger bigIntegerValue() { return BigInteger.valueOf(_value); }
@Override
public String asText() {
return NumberOutput.toString(_value);
}
@Override
public boolean asBoolean(boolean defaultValue) {
return _value != 0;
}
@Override
public final void serialize(JsonGenerator jg, SerializerProvider provider)
throws IOException, JsonProcessingException
{
jg.writeNumber(_value);
}
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o instanceof LongNode) {
return ((LongNode) o)._value == _value;
}
return false;
}
@Override
public int hashCode() {
return ((int) _value) ^ (int) (_value >> 32);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.io.CharTypes;
import com.fasterxml.jackson.core.io.NumberInput;
import com.fasterxml.jackson.core.util.ByteArrayBuilder;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* Value node that contains a text value.
*/
public class TextNode
extends ValueNode
{
final static TextNode EMPTY_STRING_NODE = new TextNode("");
protected final String _value;
public TextNode(String v) { _value = v; }
/**
* Factory method that should be used to construct instances.
* For some common cases, can reuse canonical instances: currently
* this is the case for empty Strings, in future possible for
* others as well. If null is passed, will return null.
*
* @return Resulting {@link TextNode} object, if <b>v</b>
* is NOT null; null if it is.
*/
public static TextNode valueOf(String v)
{
if (v == null) {
return null;
}
if (v.length() == 0) {
return EMPTY_STRING_NODE;
}
return new TextNode(v);
}
@Override
public JsonNodeType getNodeType() {
return JsonNodeType.STRING;
}
@Override public JsonToken asToken() { return JsonToken.VALUE_STRING; }
@Override
public String textValue() {
return _value;
}
/**
* Method for accessing textual contents assuming they were
* base64 encoded; if so, they are decoded and resulting binary
* data is returned.
*/
public byte[] getBinaryValue(Base64Variant b64variant) throws IOException
{
@SuppressWarnings("resource")
ByteArrayBuilder builder = new ByteArrayBuilder(100);
final String str = _value;
int ptr = 0;
int len = str.length();
main_loop:
while (ptr < len) {
// first, we'll skip preceding white space, if any
char ch;
do {
ch = str.charAt(ptr++);
if (ptr >= len) {
break main_loop;
}
} while (ch <= ' ');
int bits = b64variant.decodeBase64Char(ch);
if (bits < 0) {
_reportInvalidBase64(b64variant, ch, 0);
}
int decodedData = bits;
// then second base64 char; can't get padding yet, nor ws
if (ptr >= len) {
_reportBase64EOF();
}
ch = str.charAt(ptr++);
bits = b64variant.decodeBase64Char(ch);
if (bits < 0) {
_reportInvalidBase64(b64variant, ch, 1);
}
decodedData = (decodedData << 6) | bits;
// third base64 char; can be padding, but not ws
if (ptr >= len) {
// but as per [JACKSON-631] can be end-of-input, iff not using padding
if (!b64variant.uses
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.impl;
import java.io.IOException;
import java.lang.annotation.Annotation;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.*;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
/**
* Specialized {@link SettableBeanProperty} implementation used
* for virtual property that represents Object Id that is used
* for some POJO types (or properties).
*/
public final class ObjectIdValueProperty
extends SettableBeanProperty
{
private static final long serialVersionUID = 1L;
protected final ObjectIdReader _objectIdReader;
@Deprecated // since 2.2
public ObjectIdValueProperty(ObjectIdReader objectIdReader) {
this(objectIdReader, PropertyMetadata.STD_REQUIRED);
}
public ObjectIdValueProperty(ObjectIdReader objectIdReader,
PropertyMetadata metadata)
{
super(objectIdReader.propertyName, objectIdReader.getIdType(), metadata,
objectIdReader.getDeserializer());
_objectIdReader = objectIdReader;
}
protected ObjectIdValueProperty(ObjectIdValueProperty src, JsonDeserializer<?> deser)
{
super(src, deser);
_objectIdReader = src._objectIdReader;
}
@Deprecated // since 2.3
protected ObjectIdValueProperty(ObjectIdValueProperty src, PropertyName newName) {
super(src, newName);
_objectIdReader = src._objectIdReader;
}
@Deprecated // since 2.3
protected ObjectIdValueProperty(ObjectIdValueProperty src, String newName) {
this(src, new PropertyName(newName));
}
@Override
public ObjectIdValueProperty withName(PropertyName newName) {
return new ObjectIdValueProperty(this, newName);
}
@Override
public ObjectIdValueProperty withValueDeserializer(JsonDeserializer<?> deser) {
return new ObjectIdValueProperty(this, deser);
}
// // // BeanProperty impl
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return null;
}
@Override public AnnotatedMember getMember() { return null; }
/*
/**********************************************************
/* Deserialization methods
/**********************************************************
*/
@Override
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt,
Object instance) throws IOException
{
deserializeSetAndReturn(jp, ctxt, instance);
}
@Override
public Object deserializeSetAndReturn(JsonParser jp,
DeserializationContext ctxt, Object instance) throws IOException
{
// note: no null checks (unlike usually); deserializer should fail if one found
Object id = _valueDeserializer.deserialize(jp, ctxt);
ReadableObjectId roid = ctxt.findObjectId(id, _objectIdReader.generator, _objectIdReader.resolver);
roid.bindItem(instance);
// also: may need to set a property value as well
SettableBeanProperty idProp = _objectIdReader.idProperty;
if (idProp != null) {
return idProp.setAndReturn(instance, id);
}
return instance;
}
@Override
public void set(Object instance, Object value) throws IOException {
setAndReturn(instance, value);
}
@Override
public Object setAndReturn(Object instance, Object value) throws IOException
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.io.NumberOutput;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* Numeric node that contains simple 16-bit integer values.
*/
public class ShortNode
extends NumericNode
{
protected final short _value;
/*
************************************************
* Construction
************************************************
*/
public ShortNode(short v) { _value = v; }
public static ShortNode valueOf(short l) { return new ShortNode(l); }
/*
************************************************
* Overridden JsonNode methods
************************************************
*/
@Override public JsonToken asToken() { return JsonToken.VALUE_NUMBER_INT; }
@Override
public JsonParser.NumberType numberType() { return JsonParser.NumberType.INT; } // should be SHORT
@Override
public boolean isIntegralNumber() { return true; }
@Override
public boolean isShort() { return true; }
@Override public boolean canConvertToInt() { return true; }
@Override public boolean canConvertToLong() { return true; }
@Override
public Number numberValue() {
return Short.valueOf(_value);
}
@Override
public short shortValue() { return _value; }
@Override
public int intValue() { return _value; }
@Override
public long longValue() { return _value; }
@Override
public float floatValue() { return _value; }
@Override
public double doubleValue() { return _value; }
@Override
public BigDecimal decimalValue() { return BigDecimal.valueOf(_value); }
@Override
public BigInteger bigIntegerValue() { return BigInteger.valueOf(_value); }
@Override
public String asText() {
return NumberOutput.toString(_value);
}
@Override
public boolean asBoolean(boolean defaultValue) {
return _value != 0;
}
@Override
public final void serialize(JsonGenerator jg, SerializerProvider provider)
throws IOException, JsonProcessingException
{
jg.writeNumber(_value);
}
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o instanceof ShortNode) {
return ((ShortNode) o)._value == _value;
}
return false;
}
@Override
public int hashCode() {
return _value;
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ValueInstantiator;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
/**
* We need a custom deserializer both because {@link ArrayBlockingQueue} has no
* default constructor AND because it has size limit used for constructing
* underlying storage automatically.
*/
public class ArrayBlockingQueueDeserializer
extends CollectionDeserializer
{
private static final long serialVersionUID = 1;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
/**
* Constructor used when creating contextualized instances.
*/
public ArrayBlockingQueueDeserializer(JavaType collectionType,
JsonDeserializer<Object> valueDeser, TypeDeserializer valueTypeDeser,
ValueInstantiator valueInstantiator,
JsonDeserializer<Object> delegateDeser)
{
super(collectionType, valueDeser, valueTypeDeser, valueInstantiator, delegateDeser);
}
/**
* Copy-constructor that can be used by sub-classes to allow
* copy-on-write styling copying of settings of an existing instance.
*/
protected ArrayBlockingQueueDeserializer(ArrayBlockingQueueDeserializer src) {
super(src);
}
/**
* Fluent-factory method call to construct contextual instance.
*/
@Override
@SuppressWarnings("unchecked")
protected ArrayBlockingQueueDeserializer withResolved(JsonDeserializer<?> dd,
JsonDeserializer<?> vd, TypeDeserializer vtd)
{
if ((dd == _delegateDeserializer) && (vd == _valueDeserializer) && (vtd == _valueTypeDeserializer)) {
return this;
}
return new ArrayBlockingQueueDeserializer(_collectionType,
(JsonDeserializer<Object>) vd, vtd,
_valueInstantiator, (JsonDeserializer<Object>) dd);
}
/*
/**********************************************************
/* JsonDeserializer API
/**********************************************************
*/
@SuppressWarnings("unchecked")
@Override
public Collection<Object> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
if (_delegateDeserializer != null) {
return (Collection<Object>) _valueInstantiator.createUsingDelegate(ctxt,
_delegateDeserializer.deserialize(jp, ctxt));
}
if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
String str = jp.getText();
if (str.length() == 0) {
return (Collection<Object>) _valueInstantiator.createFromString(ctxt, str);
}
}
return deserialize(jp, ctxt, null);
}
@Override
public Collection<Object> deserialize(JsonParser jp, DeserializationContext ctxt, Collection<Object> result0) throws IOException
{
// Ok: must point to START_ARRAY (or equivalent)
if (!jp.isExpectedStartArrayToken()) {
return handleNonArray(jp, ctxt, new ArrayBlockingQueue<Object>(1));
}
ArrayList<Object> tmp = new ArrayList<Object>();
JsonDeserializer<Object> valueDes = _valueDeserializer;
JsonToken t;
final TypeDeserializer typeDeser = _valueTypeDeserializer;
try {
while ((
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>t = jp.nextToken()) != JsonToken.END_ARRAY) {
Object value;
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue();
} else if (typeDeser == null) {
value = valueDes.deserialize(jp, ctxt);
} else {
value = valueDes.deserializeWithType(jp, ctxt, typeDeser);
}
tmp.add(value);
}
} catch (Exception e) {
throw JsonMappingException.wrapWithPath(e, tmp, tmp.size());
}
if (result0 != null) {
result0.addAll(tmp);
return result0;
}
return new ArrayBlockingQueue<Object>(tmp.size(), false, tmp);
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
// In future could check current token... for now this should be enough:
return typeDeserializer.deserializeTypedFromArray(jp, ctxt);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.base.ParserMinimalBase;
import com.fasterxml.jackson.databind.JsonNode;
/**
* Facade over {@link JsonNode} that implements {@link JsonParser} to allow
* accessing contents of JSON tree in alternate form (stream of tokens).
* Useful when a streaming source is expected by code, such as data binding
* functionality.
*/
public class TreeTraversingParser extends ParserMinimalBase
{
/*
/**********************************************************
/* Configuration
/**********************************************************
*/
protected ObjectCodec _objectCodec;
/**
* Traversal context within tree
*/
protected NodeCursor _nodeCursor;
/*
/**********************************************************
/* State
/**********************************************************
*/
/**
* Sometimes parser needs to buffer a single look-ahead token; if so,
* it'll be stored here. This is currently used for handling
*/
protected JsonToken _nextToken;
/**
* Flag needed to handle recursion into contents of child
* Array/Object nodes.
*/
protected boolean _startContainer;
/**
* Flag that indicates whether parser is closed or not. Gets
* set when parser is either closed by explicit call
* ({@link #close}) or when end-of-input is reached.
*/
protected boolean _closed;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public TreeTraversingParser(JsonNode n) { this(n, null); }
public TreeTraversingParser(JsonNode n, ObjectCodec codec)
{
super(0);
_objectCodec = codec;
if (n.isArray()) {
_nextToken = JsonToken.START_ARRAY;
_nodeCursor = new NodeCursor.Array(n, null);
} else if (n.isObject()) {
_nextToken = JsonToken.START_OBJECT;
_nodeCursor = new NodeCursor.Object(n, null);
} else { // value node
_nodeCursor = new NodeCursor.RootValue(n, null);
}
}
@Override
public void setCodec(ObjectCodec c) {
_objectCodec = c;
}
@Override
public ObjectCodec getCodec() {
return _objectCodec;
}
@Override
public Version version() {
return com.fasterxml.jackson.databind.cfg.PackageVersion.VERSION;
}
/*
/**********************************************************
/* Closeable implementation
/**********************************************************
*/
@Override
public void close() throws IOException
{
if (!_closed) {
_closed = true;
_nodeCursor = null;
_currToken = null;
}
}
/*
/**********************************************************
/* Public API, traversal
/**********************************************************
*/
@Override
public JsonToken nextToken() throws IOException, JsonParseException
{
if (_nextToken != null) {
_currToken = _nextToken;
_nextToken = null;
return _currToken;
}
// are we to descend to a container child?
if (_startContainer) {
_startContainer = false;
// minor optimization: empty containers can be skipped
if (!_nodeCursor.currentHasChildren()) {
_
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>currToken = (_currToken == JsonToken.START_OBJECT) ?
JsonToken.END_OBJECT : JsonToken.END_ARRAY;
return _currToken;
}
_nodeCursor = _nodeCursor.iterateChildren();
_currToken = _nodeCursor.nextToken();
if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) {
_startContainer = true;
}
return _currToken;
}
// No more content?
if (_nodeCursor == null) {
_closed = true; // if not already set
return null;
}
// Otherwise, next entry from current cursor
_currToken = _nodeCursor.nextToken();
if (_currToken != null) {
if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) {
_startContainer = true;
}
return _currToken;
}
// null means no more children; need to return end marker
_currToken = _nodeCursor.endToken();
_nodeCursor = _nodeCursor.getParent();
return _currToken;
}
// default works well here:
//public JsonToken nextValue() throws IOException, JsonParseException
@Override
public JsonParser skipChildren() throws IOException, JsonParseException
{
if (_currToken == JsonToken.START_OBJECT) {
_startContainer = false;
_currToken = JsonToken.END_OBJECT;
} else if (_currToken == JsonToken.START_ARRAY) {
_startContainer = false;
_currToken = JsonToken.END_ARRAY;
}
return this;
}
@Override
public boolean isClosed() {
return _closed;
}
/*
/**********************************************************
/* Public API, token accessors
/**********************************************************
*/
@Override
public String getCurrentName() {
return (_nodeCursor == null) ? null : _nodeCursor.getCurrentName();
}
@Override
public void overrideCurrentName(String name)
{
if (_nodeCursor != null) {
_nodeCursor.overrideCurrentName(name);
}
}
@Override
public JsonStreamContext getParsingContext() {
return _nodeCursor;
}
@Override
public JsonLocation getTokenLocation() {
return JsonLocation.NA;
}
@Override
public JsonLocation getCurrentLocation() {
return JsonLocation.NA;
}
/*
/**********************************************************
/* Public API, access to textual content
/**********************************************************
*/
@Override
public String getText()
{
if (_closed) {
return null;
}
// need to separate handling a bit...
switch (_currToken) {
case FIELD_NAME:
return _nodeCursor.getCurrentName();
case VALUE_STRING:
return currentNode().textValue();
case VALUE_NUMBER_INT:
case VALUE_NUMBER_FLOAT:
return String.valueOf(currentNode().numberValue());
case VALUE_EMBEDDED_OBJECT:
JsonNode n = currentNode();
if (n != null && n.isBinary()) {
// this will convert it to base64
return n.asText();
}
default:
return (_currToken == null) ? null : _currToken.asString();
}
}
@Override
public char[] getTextCharacters() throws IOException, JsonParseException {
return getText().
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> == null) {
return null;
}
return _nodeCursor.currentNode();
}
protected JsonNode currentNumericNode()
throws JsonParseException
{
JsonNode n = currentNode();
if (n == null || !n.isNumber()) {
JsonToken t = (n == null) ? null : n.asToken();
throw _constructError("Current token ("+t+") not numeric, can not use numeric value accessors");
}
return n;
}
@Override
protected void _handleEOF() throws JsonParseException {
_throwInternal(); // should never get called
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.io.NumberOutput;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* <code>JsonNode</code> implementation for efficiently containing 32-bit
* `float` values.
*
* @since 2.2
*/
public class FloatNode extends NumericNode
{
protected final float _value;
/*
/**********************************************************
/* Construction
/**********************************************************
*/
public FloatNode(float v) { _value = v; }
public static FloatNode valueOf(float v) { return new FloatNode(v); }
/*
/**********************************************************
/* BaseJsonNode extended API
/**********************************************************
*/
@Override public JsonToken asToken() { return JsonToken.VALUE_NUMBER_FLOAT; }
@Override
public JsonParser.NumberType numberType() { return JsonParser.NumberType.FLOAT; }
/*
/**********************************************************
/* Overrridden JsonNode methods
/**********************************************************
*/
@Override
public boolean isFloatingPointNumber() { return true; }
@Override
public boolean isFloat() { return true; }
@Override public boolean canConvertToInt() {
return (_value >= Integer.MIN_VALUE && _value <= Integer.MAX_VALUE);
}
@Override public boolean canConvertToLong() {
return (_value >= Long.MIN_VALUE && _value <= Long.MAX_VALUE);
}
@Override
public Number numberValue() {
return Float.valueOf(_value);
}
@Override
public short shortValue() { return (short) _value; }
@Override
public int intValue() { return (int) _value; }
@Override
public long longValue() { return (long) _value; }
@Override
public float floatValue() { return (float) _value; }
@Override
public double doubleValue() { return _value; }
@Override
public BigDecimal decimalValue() { return BigDecimal.valueOf(_value); }
@Override
public BigInteger bigIntegerValue() {
return decimalValue().toBigInteger();
}
@Override
public String asText() {
return NumberOutput.toString(_value);
}
@Override
public final void serialize(JsonGenerator jg, SerializerProvider provider)
throws IOException, JsonProcessingException
{
jg.writeNumber(_value);
}
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o instanceof FloatNode) {
// We must account for NaNs: NaN does not equal NaN, therefore we have
// to use Double.compare().
final float otherValue = ((FloatNode) o)._value;
return Float.compare(_value, otherValue) == 0;
}
return false;
}
@Override
public int hashCode() {
return Float.floatToIntBits(_value);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>) throws IOException {
return _forward.setAndReturn(instance, value);
}
public final static class PropertyReferring extends Referring {
private final ObjectIdReferenceProperty _parent;
public final Object _pojo;
public PropertyReferring(ObjectIdReferenceProperty parent,
UnresolvedForwardReference ref, Class<?> type, Object ob)
{
super(ref, type);
_parent = parent;
_pojo = ob;
}
@Override
public void handleResolvedForwardReference(Object id, Object value) throws IOException
{
if (!hasId(id)) {
throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id
+ "] that wasn't previously seen as unresolved.");
}
_parent.set(_pojo, value);
}
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> null;
try {
PropertySerializerMap serializers = _dynamicSerializers;
for (; i < len; ++i) {
elem = value[i];
if (elem == null) {
provider.defaultSerializeNull(jgen);
continue;
}
Class<?> cc = elem.getClass();
JsonSerializer<Object> serializer = serializers.serializerFor(cc);
if (serializer == null) {
// To fix [JACKSON-508]
if (_elementType.hasGenericTypes()) {
serializer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_elementType, cc), provider);
} else {
serializer = _findAndAddDynamic(serializers, cc, provider);
}
}
serializer.serialize(elem, jgen, provider);
}
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
// [JACKSON-55] Need to add reference information
/* 05-Mar-2009, tatu: But one nasty edge is when we get
* StackOverflow: usually due to infinite loop. But that gets
* hidden within an InvocationTargetException...
*/
Throwable t = e;
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
if (t instanceof Error) {
throw (Error) t;
}
throw JsonMappingException.wrapWithPath(t, elem, i);
}
}
public void serializeContentsUsing(Object[] value, JsonGenerator jgen, SerializerProvider provider,
JsonSerializer<Object> ser)
throws IOException, JsonGenerationException
{
final int len = value.length;
final TypeSerializer typeSer = _valueTypeSerializer;
int i = 0;
Object elem = null;
try {
for (; i < len; ++i) {
elem = value[i];
if (elem == null) {
provider.defaultSerializeNull(jgen);
continue;
}
if (typeSer == null) {
ser.serialize(elem, jgen, provider);
} else {
ser.serializeWithType(elem, jgen, provider, typeSer);
}
}
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
Throwable t = e;
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
if (t instanceof Error) {
throw (Error) t;
}
throw JsonMappingException.wrapWithPath(t, elem, i);
}
}
public void serializeTypedContents(Object[] value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
final int len = value.length;
final TypeSerializer typeSer = _valueTypeSerializer;
int i = 0;
Object elem = null;
try {
PropertySerializerMap serializers = _dynamicSerializers;
for (; i < len; ++i) {
elem = value[i];
if (elem == null) {
provider.defaultSerializeNull(jgen);
continue;
}
Class<?> cc = elem.getClass();
JsonSerializer<Object> serializer = serializers.serializerFor(cc);
if (serializer == null) {
serializer = _findAndAddDynamic
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>(serializers, cc, provider);
}
serializer.serializeWithType(elem, jgen, provider, typeSer);
}
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
Throwable t = e;
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
if (t instanceof Error) {
throw (Error) t;
}
throw JsonMappingException.wrapWithPath(t, elem, i);
}
}
@SuppressWarnings("deprecation")
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
throws JsonMappingException
{
ObjectNode o = createSchemaNode("array", true);
if (typeHint != null) {
JavaType javaType = provider.constructType(typeHint);
if (javaType.isArrayType()) {
Class<?> componentType = ((ArrayType) javaType).getContentType().getRawClass();
// 15-Oct-2010, tatu: We can't serialize plain Object.class; but what should it produce here? Untyped?
if (componentType == Object.class) {
o.put("items", com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode());
} else {
JsonSerializer<Object> ser = provider.findValueSerializer(componentType, _property);
JsonNode schemaNode = (ser instanceof SchemaAware) ?
((SchemaAware) ser).getSchema(provider, null) :
com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode();
o.put("items", schemaNode);
}
}
}
return o;
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
JsonArrayFormatVisitor arrayVisitor = visitor.expectArrayFormat(typeHint);
if (arrayVisitor != null) {
TypeFactory tf = visitor.getProvider().getTypeFactory();
JavaType contentType = tf.moreSpecificType(_elementType, typeHint.getContentType());
if (contentType == null) {
throw new JsonMappingException("Could not resolve type");
}
JsonSerializer<?> valueSer = _elementSerializer;
if (valueSer == null) {
valueSer = visitor.getProvider().findValueSerializer(contentType, _property);
}
arrayVisitor.itemsFormat(valueSer, contentType);
}
}
protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
Class<?> type, SerializerProvider provider) throws JsonMappingException
{
PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property);
// did we get a new map of serializers? If so, start using it
if (map != result.map) {
_dynamicSerializers = result.map;
}
return result.serializer;
}
protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
JavaType type, SerializerProvider provider) throws JsonMappingException
{
PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property);
// did we get a new map of serializers? If so, start using it
if (map != result.map) {
_dynamicSerializers =
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
/**
* Numeric node that contains values that do not fit in simple
* integer (int, long) or floating point (double) values.
*/
public class DecimalNode
extends NumericNode
{
public static final DecimalNode ZERO = new DecimalNode(BigDecimal.ZERO);
private final static BigDecimal MIN_INTEGER = BigDecimal.valueOf(Integer.MIN_VALUE);
private final static BigDecimal MAX_INTEGER = BigDecimal.valueOf(Integer.MAX_VALUE);
private final static BigDecimal MIN_LONG = BigDecimal.valueOf(Long.MIN_VALUE);
private final static BigDecimal MAX_LONG = BigDecimal.valueOf(Long.MAX_VALUE);
final protected BigDecimal _value;
/*
/**********************************************************
/* Construction
/**********************************************************
*/
public DecimalNode(BigDecimal v) { _value = v; }
public static DecimalNode valueOf(BigDecimal d) { return new DecimalNode(d); }
/*
/**********************************************************
/* BaseJsonNode extended API
/**********************************************************
*/
@Override public JsonToken asToken() { return JsonToken.VALUE_NUMBER_FLOAT; }
@Override
public JsonParser.NumberType numberType() { return JsonParser.NumberType.BIG_DECIMAL; }
/*
/**********************************************************
/* Overrridden JsonNode methods
/**********************************************************
*/
@Override
public boolean isFloatingPointNumber() { return true; }
@Override
public boolean isBigDecimal() { return true; }
@Override public boolean canConvertToInt() {
return (_value.compareTo(MIN_INTEGER) >= 0) && (_value.compareTo(MAX_INTEGER) <= 0);
}
@Override public boolean canConvertToLong() {
return (_value.compareTo(MIN_LONG) >= 0) && (_value.compareTo(MAX_LONG) <= 0);
}
@Override
public Number numberValue() { return _value; }
@Override
public short shortValue() { return _value.shortValue(); }
@Override
public int intValue() { return _value.intValue(); }
@Override
public long longValue() { return _value.longValue(); }
@Override
public BigInteger bigIntegerValue() { return _value.toBigInteger(); }
@Override
public float floatValue() { return _value.floatValue(); }
@Override
public double doubleValue() { return _value.doubleValue(); }
@Override
public BigDecimal decimalValue() { return _value; }
@Override
public String asText() {
return _value.toString();
}
@Override
public final void serialize(JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException
{
// 07-Jul-2013, tatu: Should be handled by propagating setting to JsonGenerator
// so this should not be needed:
/*
if (provider.isEnabled(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN)) {
if (!(jgen instanceof TokenBuffer)) { // [Issue#232]
jgen.writeNumber(((BigDecimal) _value).toPlainString());
return;
}
}
*/
jgen.writeNumber(_value);
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> Name other = (Name) o;
return _first.equals(other._first) && _last.equals(other._last);
}
}
private Gender _gender;
private Name _name;
private boolean _isVerified;
private byte[] _userImage;
public FiveMinuteUser() { }
public FiveMinuteUser(String first, String last, boolean verified, Gender g, byte[] data)
{
_name = new Name(first, last);
_isVerified = verified;
_gender = g;
_userImage = data;
}
public Name getName() { return _name; }
public boolean isVerified() { return _isVerified; }
public Gender getGender() { return _gender; }
public byte[] getUserImage() { return _userImage; }
public void setName(Name n) { _name = n; }
public void setVerified(boolean b) { _isVerified = b; }
public void setGender(Gender g) { _gender = g; }
public void setUserImage(byte[] b) { _userImage = b; }
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null || o.getClass() != getClass()) return false;
FiveMinuteUser other = (FiveMinuteUser) o;
if (_isVerified != other._isVerified) return false;
if (_gender != other._gender) return false;
if (!_name.equals(other._name)) return false;
byte[] otherImage = other._userImage;
if (otherImage.length != _userImage.length) return false;
for (int i = 0, len = _userImage.length; i < len; ++i) {
if (_userImage[i] != otherImage[i]) {
return false;
}
}
return true;
}
}
/*
/**********************************************************
/* High-level helpers
/**********************************************************
*/
protected void verifyJsonSpecSampleDoc(JsonParser jp, boolean verifyContents)
throws IOException
{
verifyJsonSpecSampleDoc(jp, verifyContents, true);
}
protected void verifyJsonSpecSampleDoc(JsonParser jp, boolean verifyContents,
boolean requireNumbers)
throws IOException
{
if (!jp.hasCurrentToken()) {
jp.nextToken();
}
assertToken(JsonToken.START_OBJECT, jp.getCurrentToken()); // main object
assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Image'
if (verifyContents) {
verifyFieldName(jp, "Image");
}
assertToken(JsonToken.START_OBJECT, jp.nextToken()); // 'image' object
assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Width'
if (verifyContents) {
verifyFieldName(jp, "Width");
}
verifyIntToken(jp.nextToken(), requireNumbers);
if (verifyContents) {
verifyIntValue(jp, SAMPLE_SPEC_VALUE_WIDTH);
}
assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Height'
if (verifyContents) {
verifyFieldName(jp, "Height");
}
verifyIntToken(jp.nextToken(), requireNumbers);
if (verifyContents) {
verifyIntValue(jp, SAMPLE_SPEC_
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>VALUE_HEIGHT);
}
assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Title'
if (verifyContents) {
verifyFieldName(jp, "Title");
}
assertToken(JsonToken.VALUE_STRING, jp.nextToken());
assertEquals(SAMPLE_SPEC_VALUE_TITLE, getAndVerifyText(jp));
assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Thumbnail'
if (verifyContents) {
verifyFieldName(jp, "Thumbnail");
}
assertToken(JsonToken.START_OBJECT, jp.nextToken()); // 'thumbnail' object
assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Url'
if (verifyContents) {
verifyFieldName(jp, "Url");
}
assertToken(JsonToken.VALUE_STRING, jp.nextToken());
if (verifyContents) {
assertEquals(SAMPLE_SPEC_VALUE_TN_URL, getAndVerifyText(jp));
}
assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Height'
if (verifyContents) {
verifyFieldName(jp, "Height");
}
verifyIntToken(jp.nextToken(), requireNumbers);
if (verifyContents) {
verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_HEIGHT);
}
assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Width'
if (verifyContents) {
verifyFieldName(jp, "Width");
}
// Width value is actually a String in the example
assertToken(JsonToken.VALUE_STRING, jp.nextToken());
if (verifyContents) {
assertEquals(SAMPLE_SPEC_VALUE_TN_WIDTH, getAndVerifyText(jp));
}
assertToken(JsonToken.END_OBJECT, jp.nextToken()); // 'thumbnail' object
assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'IDs'
assertToken(JsonToken.START_ARRAY, jp.nextToken()); // 'ids' array
verifyIntToken(jp.nextToken(), requireNumbers); // ids[0]
if (verifyContents) {
verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_ID1);
}
verifyIntToken(jp.nextToken(), requireNumbers); // ids[1]
if (verifyContents) {
verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_ID2);
}
verifyIntToken(jp.nextToken(), requireNumbers); // ids[2]
if (verifyContents) {
verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_ID3);
}
verifyIntToken(jp.nextToken(), requireNumbers); // ids[3]
if (verifyContents) {
verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_ID4);
}
assertToken(JsonToken.END_ARRAY, jp.nextToken()); // 'ids' array
assertToken(JsonToken.END_OBJECT, jp.nextToken()); // 'image' object
assertToken(JsonToken.END_OBJECT, jp.nextToken()); // main object
}
private void verifyIntToken(JsonToken t, boolean requireNumbers)
{
if (t == JsonToken.VALUE_NUMBER_INT) {
return;
}
if (requireNumbers) { // to get error
assertToken(JsonToken.VALUE_NUMBER_INT,
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> t);
}
// if not number, must be String
if (t != JsonToken.VALUE_STRING) {
fail("Expected INT or STRING value, got "+t);
}
}
protected void verifyFieldName(JsonParser jp, String expName)
throws IOException
{
assertEquals(expName, jp.getText());
assertEquals(expName, jp.getCurrentName());
}
protected void verifyIntValue(JsonParser jp, long expValue)
throws IOException
{
// First, via textual
assertEquals(String.valueOf(expValue), jp.getText());
}
/**
* Method that checks whether Unit tests appear to run from Ant build
* scripts.
*
* @since 1.6
*/
protected static boolean runsFromAnt() {
return "true".equals(System.getProperty("FROM_ANT"));
}
/*
/**********************************************************
/* Parser/generator construction
/**********************************************************
*/
protected JsonParser createParserUsingReader(String input)
throws IOException, JsonParseException
{
return createParserUsingReader(new JsonFactory(), input);
}
protected JsonParser createParserUsingReader(JsonFactory f, String input)
throws IOException, JsonParseException
{
return f.createParser(new StringReader(input));
}
protected JsonParser createParserUsingStream(String input, String encoding)
throws IOException, JsonParseException
{
return createParserUsingStream(new JsonFactory(), input, encoding);
}
protected JsonParser createParserUsingStream(JsonFactory f,
String input, String encoding)
throws IOException, JsonParseException
{
/* 23-Apr-2008, tatus: UTF-32 is not supported by JDK, have to
* use our own codec too (which is not optimal since there's
* a chance both encoder and decoder might have bugs, but ones
* that cancel each other out or such)
*/
byte[] data;
if (encoding.equalsIgnoreCase("UTF-32")) {
data = encodeInUTF32BE(input);
} else {
data = input.getBytes(encoding);
}
InputStream is = new ByteArrayInputStream(data);
return f.createParser(is);
}
/*
/**********************************************************
/* Additional assertion methods
/**********************************************************
*/
protected void assertToken(JsonToken expToken, JsonToken actToken)
{
if (actToken != expToken) {
fail("Expected token "+expToken+", current token "+actToken);
}
}
protected void assertToken(JsonToken expToken, JsonParser jp)
{
assertToken(expToken, jp.getCurrentToken());
}
protected void assertType(Object ob, Class<?> expType)
{
if (ob == null) {
fail("Expected an object of type "+expType.getName()+", got null");
}
Class<?> cls = ob.getClass();
if (!expType.isAssignableFrom(cls)) {
fail("Expected type "+expType.getName()+", got "+cls.getName());
}
}
protected void assertValidLocation(JsonLocation location) {
assertNotNull("Should have non-null location", location);
assertTrue("Should have positive line number", location.getLineNr() > 0);
}
protected void verifyException(Throwable e, String... matches)
{
String msg = e.getMessage();
String lmsg = (
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.JsonNode;
/**
* This intermediate base class is used for all container nodes,
* specifically, array and object nodes.
*/
public abstract class ContainerNode<T extends ContainerNode<T>>
extends BaseJsonNode
implements JsonNodeCreator
{
/**
* We will keep a reference to the Object (usually TreeMapper)
* that can construct instances of nodes to add to this container
* node.
*/
protected final JsonNodeFactory _nodeFactory;
protected ContainerNode(JsonNodeFactory nc)
{
_nodeFactory = nc;
}
// all containers are mutable: can't define:
// @Override public abstract <T extends JsonNode> T deepCopy();
@Override
public abstract JsonToken asToken();
@Override
public String asText() { return ""; }
/*
/**********************************************************
/* Methods reset as abstract to force real implementation
/**********************************************************
*/
@Override
public abstract int size();
@Override
public abstract JsonNode get(int index);
@Override
public abstract JsonNode get(String fieldName);
/*
/**********************************************************
/* JsonNodeCreator implementation, just dispatch to
/* the real creator
/**********************************************************
*/
/**
* Factory method that constructs and returns an empty {@link ArrayNode}
* Construction is done using registered {@link JsonNodeFactory}.
*/
@Override
public final ArrayNode arrayNode() { return _nodeFactory.arrayNode(); }
/**
* Factory method that constructs and returns an empty {@link ObjectNode}
* Construction is done using registered {@link JsonNodeFactory}.
*/
@Override
public final ObjectNode objectNode() { return _nodeFactory.objectNode(); }
@Override
public final NullNode nullNode() { return _nodeFactory.nullNode(); }
@Override
public final BooleanNode booleanNode(boolean v) { return _nodeFactory.booleanNode(v); }
@Override
public final NumericNode numberNode(byte v) { return _nodeFactory.numberNode(v); }
@Override
public final NumericNode numberNode(short v) { return _nodeFactory.numberNode(v); }
@Override
public final NumericNode numberNode(int v) { return _nodeFactory.numberNode(v); }
@Override
public final NumericNode numberNode(long v) {
return _nodeFactory.numberNode(v);
}
// was missing from 2.2 and before
@Override
public final NumericNode numberNode(BigInteger v) { return _nodeFactory.numberNode(v); }
@Override
public final NumericNode numberNode(float v) { return _nodeFactory.numberNode(v); }
@Override
public final NumericNode numberNode(double v) { return _nodeFactory.numberNode(v); }
@Override
public final NumericNode numberNode(BigDecimal v) { return (_nodeFactory.numberNode(v)); }
// // Wrapper types, missing from 2.2 and before
@Override
public final ValueNode numberNode(Byte v) { return _nodeFactory.numberNode(v); }
@Override
public final ValueNode numberNode(Short v) { return _nodeFactory.numberNode(v); }
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
public class StackTraceElementDeserializer
extends StdScalarDeserializer<StackTraceElement>
{
private static final long serialVersionUID = 1L;
public StackTraceElementDeserializer() { super(StackTraceElement.class); }
@Override
public StackTraceElement deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
JsonToken t = jp.getCurrentToken();
// Must get an Object
if (t == JsonToken.START_OBJECT) {
String className = "", methodName = "", fileName = "";
int lineNumber = -1;
while ((t = jp.nextValue()) != JsonToken.END_OBJECT) {
String propName = jp.getCurrentName();
if ("className".equals(propName)) {
className = jp.getText();
} else if ("fileName".equals(propName)) {
fileName = jp.getText();
} else if ("lineNumber".equals(propName)) {
if (t.isNumeric()) {
lineNumber = jp.getIntValue();
} else {
throw JsonMappingException.from(jp, "Non-numeric token ("+t+") for property 'lineNumber'");
}
} else if ("methodName".equals(propName)) {
methodName = jp.getText();
} else if ("nativeMethod".equals(propName)) {
// no setter, not passed via constructor: ignore
} else {
handleUnknownProperty(jp, ctxt, _valueClass, propName);
}
}
return new StackTraceElement(className, methodName, fileName, lineNumber);
} else if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final StackTraceElement value = deserialize(jp, ctxt);
if (jp.nextToken() != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'java.lang.StackTraceElement' value but there was more than a single value in the array"
);
}
return value;
}
throw ctxt.mappingException(_valueClass, t);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> Deserializer API
/**********************************************************
*/
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
switch (jp.getCurrentToken()) {
case FIELD_NAME:
case START_OBJECT:
if (_mapDeserializer != null) {
return _mapDeserializer.deserialize(jp, ctxt);
}
return mapObject(jp, ctxt);
case START_ARRAY:
if (ctxt.isEnabled(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
return mapArrayToArray(jp, ctxt);
}
if (_listDeserializer != null) {
return _listDeserializer.deserialize(jp, ctxt);
}
return mapArray(jp, ctxt);
case VALUE_EMBEDDED_OBJECT:
return jp.getEmbeddedObject();
case VALUE_STRING:
if (_stringDeserializer != null) {
return _stringDeserializer.deserialize(jp, ctxt);
}
return jp.getText();
case VALUE_NUMBER_INT:
if (_numberDeserializer != null) {
return _numberDeserializer.deserialize(jp, ctxt);
}
/* [JACKSON-100]: caller may want to get all integral values
* returned as BigInteger, for consistency
*/
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS)) {
return jp.getBigIntegerValue(); // should be optimal, whatever it is
}
return jp.getNumberValue(); // should be optimal, whatever it is
case VALUE_NUMBER_FLOAT:
if (_numberDeserializer != null) {
return _numberDeserializer.deserialize(jp, ctxt);
}
/* [JACKSON-72]: need to allow overriding the behavior regarding
* which type to use
*/
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
return jp.getDecimalValue();
}
return Double.valueOf(jp.getDoubleValue());
case VALUE_TRUE:
return Boolean.TRUE;
case VALUE_FALSE:
return Boolean.FALSE;
case VALUE_NULL: // should not get this but...
return null;
case END_ARRAY: // invalid
case END_OBJECT: // invalid
default:
throw ctxt.mappingException(Object.class);
}
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException
{
JsonToken t = jp.getCurrentToken();
switch (t) {
// First: does it look like we had type id wrapping of some kind?
case START_ARRAY:
case START_OBJECT:
case FIELD_NAME:
/* Output can be as JSON Object, Array or scalar: no way to know
* a this point:
*/
return typeDeserializer.deserializeTypedFromAny(jp, ctxt);
/* Otherwise we probably got a "native" type (ones that map
* naturally and thus do not need or use type ids)
*/
case VALUE_STRING:
if (_stringDeserializer != null) {
return _stringDeserializer.deserialize(jp, ctxt);
}
return jp.getText();
case VALUE_NUMBER_INT:
if (_numberDeserializer != null) {
return _numberDeserializer.deserialize(jp, ctxt);
}
// For [JACKSON-100], see above:
if (ctxt.isEnabled(Deserialization
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>Feature.USE_BIG_INTEGER_FOR_INTS)) {
return jp.getBigIntegerValue();
}
/* and as per [JACKSON-839], allow "upgrade" to bigger types: out-of-range
* entries can not be produced without type, so this should "just work",
* even if it is bit unclean
*/
return jp.getNumberValue();
case VALUE_NUMBER_FLOAT:
if (_numberDeserializer != null) {
return _numberDeserializer.deserialize(jp, ctxt);
}
// For [JACKSON-72], see above
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
return jp.getDecimalValue();
}
return Double.valueOf(jp.getDoubleValue());
case VALUE_TRUE:
return Boolean.TRUE;
case VALUE_FALSE:
return Boolean.FALSE;
case VALUE_EMBEDDED_OBJECT:
return jp.getEmbeddedObject();
case VALUE_NULL: // should not get this far really but...
return null;
default:
throw ctxt.mappingException(Object.class);
}
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
/**
* Method called to map a JSON Array into a Java value.
*/
protected Object mapArray(JsonParser jp, DeserializationContext ctxt) throws IOException
{
// Minor optimization to handle small lists (default size for ArrayList is 10)
if (jp.nextToken() == JsonToken.END_ARRAY) {
return new ArrayList<Object>(2);
}
Object value = deserialize(jp, ctxt);
if (jp.nextToken() == JsonToken.END_ARRAY) {
ArrayList<Object> l = new ArrayList<Object>(2);
l.add(value);
return l;
}
Object value2 = deserialize(jp, ctxt);
if (jp.nextToken() == JsonToken.END_ARRAY) {
ArrayList<Object> l = new ArrayList<Object>(2);
l.add(value);
l.add(value2);
return l;
}
ObjectBuffer buffer = ctxt.leaseObjectBuffer();
Object[] values = buffer.resetAndStart();
int ptr = 0;
values[ptr++] = value;
values[ptr++] = value2;
int totalSize = ptr;
do {
value = deserialize(jp, ctxt);
++totalSize;
if (ptr >= values.length) {
values = buffer.appendCompletedChunk(values);
ptr = 0;
}
values[ptr++] = value;
} while (jp.nextToken() != JsonToken.END_ARRAY);
// let's create full array then
ArrayList<Object> result = new ArrayList<Object>(totalSize);
buffer.completeAndClearBuffer(values, ptr, result);
return result;
}
/**
* Method called to map a JSON Object into a Java value.
*/
protected Object mapObject(JsonParser jp, DeserializationContext ctxt) throws IOException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.START_OBJECT) {
t = jp.nextToken();
}
// minor optimization; let's handle 1 and 2 entry cases separately
if (t == JsonToken.END_OBJECT) { // and empty one too
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
// empty map might work; but caller may want to modify... so better just give small modifiable
return new LinkedHashMap<String,Object>(2);
}
String field1 = jp.getCurrentName();
jp.nextToken();
Object value1 = deserialize(jp, ctxt);
if (jp.nextToken() == JsonToken.END_OBJECT) { // single entry; but we want modifiable
LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>(2);
result.put(field1, value1);
return result;
}
String field2 = jp.getCurrentName();
jp.nextToken();
Object value2 = deserialize(jp, ctxt);
if (jp.nextToken() == JsonToken.END_OBJECT) {
LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>(4);
result.put(field1, value1);
result.put(field2, value2);
return result;
}
// And then the general case; default map size is 16
LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>();
result.put(field1, value1);
result.put(field2, value2);
do {
String fieldName = jp.getCurrentName();
jp.nextToken();
result.put(fieldName, deserialize(jp, ctxt));
} while (jp.nextToken() != JsonToken.END_OBJECT);
return result;
}
/**
* Method called to map a JSON Array into a Java Object array (Object[]).
*/
protected Object[] mapArrayToArray(JsonParser jp, DeserializationContext ctxt) throws IOException
{
// Minor optimization to handle small lists (default size for ArrayList is 10)
if (jp.nextToken() == JsonToken.END_ARRAY) {
return NO_OBJECTS;
}
ObjectBuffer buffer = ctxt.leaseObjectBuffer();
Object[] values = buffer.resetAndStart();
int ptr = 0;
do {
Object value = deserialize(jp, ctxt);
if (ptr >= values.length) {
values = buffer.appendCompletedChunk(values);
ptr = 0;
}
values[ptr++] = value;
} while (jp.nextToken() != JsonToken.END_ARRAY);
return buffer.completeAndClearBuffer(values, ptr);
}
/*
/**********************************************************
/* Separate "vanilla" implementation for common case of
/* no custom deserializer overrides
/**********************************************************
*/
@JacksonStdImpl
public static class Vanilla
extends StdDeserializer<Object>
{
private static final long serialVersionUID = 1L;
public final static Vanilla std = new Vanilla();
public Vanilla() { super(Object.class); }
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
switch (jp.getCurrentTokenId()) {
case JsonTokenId.ID_START_OBJECT:
{
JsonToken t = jp.nextToken();
if (t == JsonToken.END_OBJECT) {
return new LinkedHashMap<String,Object>(2);
}
}
case JsonTokenId.ID_FIELD_NAME:
return mapObject(jp, ctxt);
case JsonTokenId.ID_START_ARRAY:
{
JsonToken t = jp.nextToken();
if (t == JsonToken.END_ARRAY)
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> { // and empty one too
if (ctxt.isEnabled(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
return NO_OBJECTS;
}
return new ArrayList<Object>(2);
}
}
if (ctxt.isEnabled(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
return mapArrayToArray(jp, ctxt);
}
return mapArray(jp, ctxt);
case JsonTokenId.ID_EMBEDDED_OBJECT:
return jp.getEmbeddedObject();
case JsonTokenId.ID_STRING:
return jp.getText();
case JsonTokenId.ID_NUMBER_INT:
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS)) {
return jp.getBigIntegerValue(); // should be optimal, whatever it is
}
return jp.getNumberValue(); // should be optimal, whatever it is
case JsonTokenId.ID_NUMBER_FLOAT:
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
return jp.getDecimalValue();
}
return Double.valueOf(jp.getDoubleValue());
case JsonTokenId.ID_TRUE:
return Boolean.TRUE;
case JsonTokenId.ID_FALSE:
return Boolean.FALSE;
case JsonTokenId.ID_NULL: // should not get this but...
return null;
//case JsonTokenId.ID_END_ARRAY: // invalid
//case JsonTokenId.ID_END_OBJECT: // invalid
default:
throw ctxt.mappingException(Object.class);
}
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException
{
switch (jp.getCurrentTokenId()) {
case JsonTokenId.ID_START_ARRAY:
case JsonTokenId.ID_START_OBJECT:
case JsonTokenId.ID_FIELD_NAME:
return typeDeserializer.deserializeTypedFromAny(jp, ctxt);
case JsonTokenId.ID_STRING:
return jp.getText();
case JsonTokenId.ID_NUMBER_INT:
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS)) {
return jp.getBigIntegerValue();
}
return jp.getNumberValue();
case JsonTokenId.ID_NUMBER_FLOAT:
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
return jp.getDecimalValue();
}
return Double.valueOf(jp.getDoubleValue());
case JsonTokenId.ID_TRUE:
return Boolean.TRUE;
case JsonTokenId.ID_FALSE:
return Boolean.FALSE;
case JsonTokenId.ID_EMBEDDED_OBJECT:
return jp.getEmbeddedObject();
case JsonTokenId.ID_NULL: // should not get this far really but...
return null;
default:
throw ctxt.mappingException(Object.class);
}
}
protected Object mapArray(JsonParser jp, DeserializationContext ctxt) throws IOException
{
Object value = deserialize(jp, ctxt);
if (jp.nextToken() == JsonToken.END_ARRAY) {
ArrayList<Object> l = new ArrayList<Object>(2);
l.add(value);
return l;
}
Object value2 =
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> deserialize(jp, ctxt);
if (jp.nextToken() == JsonToken.END_ARRAY) {
ArrayList<Object> l = new ArrayList<Object>(2);
l.add(value);
l.add(value2);
return l;
}
ObjectBuffer buffer = ctxt.leaseObjectBuffer();
Object[] values = buffer.resetAndStart();
int ptr = 0;
values[ptr++] = value;
values[ptr++] = value2;
int totalSize = ptr;
do {
value = deserialize(jp, ctxt);
++totalSize;
if (ptr >= values.length) {
values = buffer.appendCompletedChunk(values);
ptr = 0;
}
values[ptr++] = value;
} while (jp.nextToken() != JsonToken.END_ARRAY);
// let's create full array then
ArrayList<Object> result = new ArrayList<Object>(totalSize);
buffer.completeAndClearBuffer(values, ptr, result);
return result;
}
/**
* Method called to map a JSON Object into a Java value.
*/
protected Object mapObject(JsonParser jp, DeserializationContext ctxt) throws IOException
{
// will point to FIELD_NAME at this point, guaranteed
String field1 = jp.getText();
jp.nextToken();
Object value1 = deserialize(jp, ctxt);
if (jp.nextToken() == JsonToken.END_OBJECT) { // single entry; but we want modifiable
LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>(2);
result.put(field1, value1);
return result;
}
String field2 = jp.getText();
jp.nextToken();
Object value2 = deserialize(jp, ctxt);
if (jp.nextToken() == JsonToken.END_OBJECT) {
LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>(4);
result.put(field1, value1);
result.put(field2, value2);
return result;
}
// And then the general case; default map size is 16
LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>();
result.put(field1, value1);
result.put(field2, value2);
do {
String fieldName = jp.getText();
jp.nextToken();
result.put(fieldName, deserialize(jp, ctxt));
} while (jp.nextToken() != JsonToken.END_OBJECT);
return result;
}
/**
* Method called to map a JSON Array into a Java Object array (Object[]).
*/
protected Object[] mapArrayToArray(JsonParser jp, DeserializationContext ctxt) throws IOException {
ObjectBuffer buffer = ctxt.leaseObjectBuffer();
Object[] values = buffer.resetAndStart();
int ptr = 0;
do {
Object value = deserialize(jp, ctxt);
if (ptr >= values.length) {
values = buffer.appendCompletedChunk(values);
ptr = 0;
}
values[ptr++] = value;
} while (jp.nextToken() != JsonToken.END_ARRAY);
return buffer.completeAndClearBuffer(values, ptr);
}
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> (classes) default typing should
* be used for. It will only be used if no explicit type information
* is found, but this enumeration further limits subset of those types.
*<p>
* Since 2.4 there are special exceptions for JSON Tree model
* types (sub-types of {@link TreeNode}: default typing is never
* applied to them
* (see <a href="https://github.com/FasterXML/jackson-databind/issues/88">Issue#88</a> for details)
*/
public enum DefaultTyping {
/**
* This value means that only properties that have
* {@link java.lang.Object} as declared type (including
* generic types without explicit type) will use default
* typing.
*/
JAVA_LANG_OBJECT,
/**
* Value that means that default typing will be used for
* properties with declared type of {@link java.lang.Object}
* or an abstract type (abstract class or interface).
* Note that this does <b>not</b> include array types.
*<p>
* Since 2.4, this does NOT apply to {@link TreeNode} and its subtypes.
*/
OBJECT_AND_NON_CONCRETE,
/**
* Value that means that default typing will be used for
* all types covered by {@link #OBJECT_AND_NON_CONCRETE}
* plus all array types for them.
*<p>
* Since 2.4, this does NOT apply to {@link TreeNode} and its subtypes.
*/
NON_CONCRETE_AND_ARRAYS,
/**
* Value that means that default typing will be used for
* all non-final types, with exception of small number of
* "natural" types (String, Boolean, Integer, Double), which
* can be correctly inferred from JSON; as well as for
* all arrays of non-final types.
*<p>
* Since 2.4, this does NOT apply to {@link TreeNode} and its subtypes.
*/
NON_FINAL
}
/**
* Customized {@link TypeResolverBuilder} that provides type resolver builders
* used with so-called "default typing"
* (see {@link ObjectMapper#enableDefaultTyping()} for details).
*<p>
* Type resolver construction is based on configuration: implementation takes care
* of only providing builders in cases where type information should be applied.
* This is important since build calls may be sent for any and all types, and
* type information should NOT be applied to all of them.
*/
public static class DefaultTypeResolverBuilder
extends StdTypeResolverBuilder
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
/**
* Definition of what types is this default typer valid for.
*/
protected final DefaultTyping _appliesFor;
public DefaultTypeResolverBuilder(DefaultTyping t) {
_appliesFor = t;
}
@Override
public TypeDeserializer buildTypeDeserializer(DeserializationConfig config,
JavaType baseType, Collection<NamedType> subtypes)
{
return useForType(baseType) ? super.buildTypeDeserializer(config, baseType, subtypes) : null;
}
@Override
public TypeSerializer buildTypeSerializer(SerializationConfig config,
JavaType baseType, Collection<NamedType>
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> subtypes)
{
return useForType(baseType) ? super.buildTypeSerializer(config, baseType, subtypes) : null;
}
/**
* Method called to check if the default type handler should be
* used for given type.
* Note: "natural types" (String, Boolean, Integer, Double) will never
* use typing; that is both due to them being concrete and final,
* and since actual serializers and deserializers will also ignore any
* attempts to enforce typing.
*/
public boolean useForType(JavaType t)
{
switch (_appliesFor) {
case NON_CONCRETE_AND_ARRAYS:
while (t.isArrayType()) {
t = t.getContentType();
}
// fall through
case OBJECT_AND_NON_CONCRETE:
return (t.getRawClass() == Object.class) || !t.isConcrete()
// [Issue#88] Should not apply to JSON tree models:
|| TreeNode.class.isAssignableFrom(t.getRawClass());
case NON_FINAL:
while (t.isArrayType()) {
t = t.getContentType();
}
// [Issue#88] Should not apply to JSON tree models:
return !t.isFinal() && !TreeNode.class.isAssignableFrom(t.getRawClass());
default:
//case JAVA_LANG_OBJECT:
return (t.getRawClass() == Object.class);
}
}
}
/*
/**********************************************************
/* Internal constants, singletons
/**********************************************************
*/
// Quick little shortcut, to avoid having to use global TypeFactory instance...
private final static JavaType JSON_NODE_TYPE = SimpleType.constructUnsafe(JsonNode.class);
/* !!! 03-Apr-2009, tatu: Should try to avoid direct reference... but not
* sure what'd be simple and elegant way. So until then:
*/
protected final static ClassIntrospector DEFAULT_INTROSPECTOR = BasicClassIntrospector.instance;
// 16-May-2009, tatu: Ditto ^^^
protected final static AnnotationIntrospector DEFAULT_ANNOTATION_INTROSPECTOR = new JacksonAnnotationIntrospector();
protected final static VisibilityChecker<?> STD_VISIBILITY_CHECKER = VisibilityChecker.Std.defaultInstance();
protected final static PrettyPrinter _defaultPrettyPrinter = new DefaultPrettyPrinter();
/**
* Base settings contain defaults used for all {@link ObjectMapper}
* instances.
*/
protected final static BaseSettings DEFAULT_BASE = new BaseSettings(DEFAULT_INTROSPECTOR,
DEFAULT_ANNOTATION_INTROSPECTOR, STD_VISIBILITY_CHECKER, null, TypeFactory.defaultInstance(),
null, StdDateFormat.instance, null,
Locale.getDefault(),
// TimeZone.getDefault()
TimeZone.getTimeZone("GMT"),
Base64Variants.getDefaultVariant() // 2.1
);
/*
/**********************************************************
/* Configuration settings, shared
/**********************************************************
*/
/**
* Factory used to create {@link JsonParser} and {@link JsonGenerator}
* instances as necessary.
*/
protected final JsonFactory _jsonFactory;
/**
* Specific factory used for creating {@link JavaType} instances;
* needed to allow modules to add more custom type handling
* (most
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>(typer);
return this;
}
/**
* Method for registering specified class as a subtype, so that
* typename-based resolution can link supertypes to subtypes
* (as an alternative to using annotations).
* Type for given class is determined from appropriate annotation;
* or if missing, default name (unqualified class name)
*/
public void registerSubtypes(Class<?>... classes) {
getSubtypeResolver().registerSubtypes(classes);
}
/**
* Method for registering specified class as a subtype, so that
* typename-based resolution can link supertypes to subtypes
* (as an alternative to using annotations).
* Name may be provided as part of argument, but if not will
* be based on annotations or use default name (unqualified
* class name).
*/
public void registerSubtypes(NamedType... types) {
getSubtypeResolver().registerSubtypes(types);
}
/*
/**********************************************************
/* Configuration, basic type handling
/**********************************************************
*/
/**
* Accessor for getting currently configured {@link TypeFactory} instance.
*/
public TypeFactory getTypeFactory() {
return _typeFactory;
}
/**
* Method that can be used to override {@link TypeFactory} instance
* used by this mapper.
*<p>
* Note: will also set {@link TypeFactory} that deserialization and
* serialization config objects use.
*/
public ObjectMapper setTypeFactory(TypeFactory f)
{
_typeFactory = f;
_deserializationConfig = _deserializationConfig.with(f);
_serializationConfig = _serializationConfig.with(f);
return this;
}
/**
* Convenience method for constructing {@link JavaType} out of given
* type (typically <code>java.lang.Class</code>), but without explicit
* context.
*/
public JavaType constructType(Type t) {
return _typeFactory.constructType(t);
}
/*
/**********************************************************
/* Configuration, deserialization
/**********************************************************
*/
/**
* Method for specifying {@link JsonNodeFactory} to use for
* constructing root level tree nodes (via method
* {@link #createObjectNode}
*/
public ObjectMapper setNodeFactory(JsonNodeFactory f) {
_deserializationConfig = _deserializationConfig.with(f);
return this;
}
/**
* Method for adding specified {@link DeserializationProblemHandler}
* to be used for handling specific problems during deserialization.
*/
public ObjectMapper addHandler(DeserializationProblemHandler h) {
_deserializationConfig = _deserializationConfig.withHandler(h);
return this;
}
/**
* Method for removing all registered {@link DeserializationProblemHandler}s
* instances from this mapper.
*/
public ObjectMapper clearProblemHandlers() {
_deserializationConfig = _deserializationConfig.withNoProblemHandlers();
return this;
}
/**
* Method that allows overriding of the underlying {@link DeserializationConfig}
* object.
* It is added as a fallback method that may be used if no other configuration
* modifier method works: it should not be used if there are alternatives,
* and its use is generally discouraged.
*<p>
* <b>NOTE</b>: only use this method if you know what you are doing -- it allows
* by-passing some
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> jp, Class<T> valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(getDeserializationConfig(), jp, _typeFactory.constructType(valueType));
}
/**
* Method to deserialize JSON content into a Java type, reference
* to which is passed as argument. Type is passed using so-called
* "super type token" (see )
* and specifically needs to be used if the root type is a
* parameterized (generic) container type.
*/
@Override
@SuppressWarnings("unchecked")
public <T> T readValue(JsonParser jp, TypeReference<?> valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(getDeserializationConfig(), jp, _typeFactory.constructType(valueTypeRef));
}
/**
* Method to deserialize JSON content into a Java type, reference
* to which is passed as argument. Type is passed using
* Jackson specific type; instance of which can be constructed using
* {@link TypeFactory}.
*/
@Override
@SuppressWarnings("unchecked")
public final <T> T readValue(JsonParser jp, ResolvedType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(getDeserializationConfig(), jp, (JavaType) valueType);
}
/**
* Type-safe overloaded method, basically alias for {@link #readValue(JsonParser, ResolvedType)}.
*/
@SuppressWarnings("unchecked")
public <T> T readValue(JsonParser jp, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(getDeserializationConfig(), jp, valueType);
}
/**
* Method to deserialize JSON content as tree expressed
* using set of {@link JsonNode} instances. Returns
* root of the resulting tree (where root can consist
* of just a single node if the current event is a
* value event, not container).
*/
@Override
public <T extends TreeNode> T readTree(JsonParser jp)
throws IOException, JsonProcessingException
{
/* 02-Mar-2009, tatu: One twist; deserialization provider
* will map JSON null straight into Java null. But what
* we want to return is the "null node" instead.
*/
/* 05-Aug-2011, tatu: Also, must check for EOF here before
* calling readValue(), since that'll choke on it otherwise
*/
DeserializationConfig cfg = getDeserializationConfig();
JsonToken t = jp.getCurrentToken();
if (t == null) {
t = jp.nextToken();
if (t == null) {
return null;
}
}
JsonNode n = (JsonNode) _readValue(cfg, jp, JSON_NODE_TYPE);
if (n == null) {
n = getNodeFactory().nullNode();
}
@SuppressWarnings("unchecked")
T result = (T) n;
return result;
}
/**
* Method for reading sequence of Objects from parser stream.
* Sequence can be either root-level "unwrapped" sequence (without surrounding
* JSON array), or a sequence contained in a JSON Array.
* In either case {@link JsonParser} must point to the first token of
* the first element, OR
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>.
*
* @since 2.3
*/
public ObjectWriter writer(ContextAttributes attrs) {
return new ObjectWriter(this, getSerializationConfig().with(attrs));
}
/*
/**********************************************************
/* Extended Public API: constructing ObjectReaders
/* for more advanced configuration
/**********************************************************
*/
/**
* Factory method for constructing {@link ObjectReader} with
* default settings. Note that the resulting instance is NOT usable as is,
* without defining expected value type.
*/
public ObjectReader reader() {
return new ObjectReader(this, getDeserializationConfig())
.with(_injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} with
* specified feature enabled (compared to settings that this
* mapper instance has).
* Note that the resulting instance is NOT usable as is,
* without defining expected value type.
*/
public ObjectReader reader(DeserializationFeature feature) {
return new ObjectReader(this, getDeserializationConfig().with(feature));
}
/**
* Factory method for constructing {@link ObjectReader} with
* specified features enabled (compared to settings that this
* mapper instance has).
* Note that the resulting instance is NOT usable as is,
* without defining expected value type.
*/
public ObjectReader reader(DeserializationFeature first,
DeserializationFeature... other) {
return new ObjectReader(this, getDeserializationConfig().with(first, other));
}
/**
* Factory method for constructing {@link ObjectReader} that will
* update given Object (usually Bean, but can be a Collection or Map
* as well, but NOT an array) with JSON data. Deserialization occurs
* normally except that the root-level value in JSON is not used for
* instantiating a new object; instead give updateable object is used
* as root.
* Runtime type of value object is used for locating deserializer,
* unless overridden by other factory methods of {@link ObjectReader}
*/
public ObjectReader readerForUpdating(Object valueToUpdate)
{
JavaType t = _typeFactory.constructType(valueToUpdate.getClass());
return new ObjectReader(this, getDeserializationConfig(), t, valueToUpdate,
null, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* read or update instances of specified type
*/
public ObjectReader reader(JavaType type)
{
return new ObjectReader(this, getDeserializationConfig(), type, null,
null, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* read or update instances of specified type
*/
public ObjectReader reader(Class<?> type)
{
return reader(_typeFactory.constructType(type));
}
/**
* Factory method for constructing {@link ObjectReader} that will
* read or update instances of specified type
*/
public ObjectReader reader(TypeReference<?> type)
{
return reader(_typeFactory.constructType(type));
}
/**
* Factory method for constructing {@link ObjectReader} that will
* use specified {@link JsonNodeFactory} for constructing JSON trees.
*/
public ObjectReader reader(JsonNodeFactory f)
{
return new ObjectReader(this, getDeserializationConfig()).with(f);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* pass
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>/unwrapping both for efficiency and
* for correctness. If root value wrapping/unwrapping is actually desired,
* caller must use explicit <code>writeValue</code> and
* <code>readValue</code> methods.
*/
@SuppressWarnings("resource")
protected Object _convert(Object fromValue, JavaType toValueType)
throws IllegalArgumentException
{
// also, as per [Issue-11], consider case for simple cast
/* But with caveats: one is that while everything is Object.class, we don't
* want to "optimize" that out; and the other is that we also do not want
* to lose conversions of generic types.
*/
Class<?> targetType = toValueType.getRawClass();
if (targetType != Object.class
&& !toValueType.hasGenericTypes()
&& targetType.isAssignableFrom(fromValue.getClass())) {
return fromValue;
}
/* Then use TokenBuffer, which is a JsonGenerator:
* (see [JACKSON-175])
*/
TokenBuffer buf = new TokenBuffer(this, false);
try {
// inlined 'writeValue' with minor changes:
// first: disable wrapping when writing
SerializationConfig config = getSerializationConfig().without(SerializationFeature.WRAP_ROOT_VALUE);
// no need to check for closing of TokenBuffer
_serializerProvider(config).serializeValue(buf, fromValue);
// then matching read, inlined 'readValue' with minor mods:
final JsonParser jp = buf.asParser();
Object result;
// ok to pass in existing feature flags; unwrapping handled by mapper
final DeserializationConfig deserConfig = getDeserializationConfig();
JsonToken t = _initForReading(jp);
if (t == JsonToken.VALUE_NULL) {
DeserializationContext ctxt = createDeserializationContext(jp, deserConfig);
result = _findRootDeserializer(ctxt, toValueType).getNullValue();
} else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) {
result = null;
} else { // pointing to event other than null
DeserializationContext ctxt = createDeserializationContext(jp, deserConfig);
JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, toValueType);
// note: no handling of unwarpping
result = deser.deserialize(jp, ctxt);
}
jp.close();
return result;
} catch (IOException e) { // should not occur, no real i/o...
throw new IllegalArgumentException(e.getMessage(), e);
}
}
/*
/**********************************************************
/* Extended Public API: JSON Schema generation
/**********************************************************
*/
/**
* Generate <a href="http://json-schema.org/">Json-schema</a>
* instance for specified class.
*
* @param t The class to generate schema for
* @return Constructed JSON schema.
*/
@SuppressWarnings("deprecation")
public com.fasterxml.jackson.databind.jsonschema.JsonSchema generateJsonSchema(Class<?> t)
throws JsonMappingException {
return _serializerProvider(getSerializationConfig()).generateJsonSchema(t);
}
/**
* Method for visiting type hierarchy for given type, using specified visitor.
*<p>
* This method can be used for things like
* generating <a href="http://json-schema.org/">Json Schema</a
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) {
jgen.flush();
}
Closeable tmpToClose = toClose;
toClose = null;
tmpToClose.close();
} finally {
if (toClose != null) {
try {
toClose.close();
} catch (IOException ioe) { }
}
}
}
/*
/**********************************************************
/* Internal methods for deserialization, overridable
/**********************************************************
*/
/**
* Internal helper method called to create an instance of {@link DeserializationContext}
* for deserializing a single root value.
* Can be overridden if a custom context is needed.
*/
protected DefaultDeserializationContext createDeserializationContext(JsonParser jp,
DeserializationConfig cfg)
{
return _deserializationContext.createInstance(cfg,
jp, _injectableValues);
}
/**
* Actual implementation of value reading+binding operation.
*/
protected Object _readValue(DeserializationConfig cfg, JsonParser jp, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
/* First: may need to read the next token, to initialize
* state (either before first read from parser, or after
* previous token has been cleared)
*/
Object result;
JsonToken t = _initForReading(jp);
if (t == JsonToken.VALUE_NULL) {
// [JACKSON-643]: Ask JsonDeserializer what 'null value' to use:
DeserializationContext ctxt = createDeserializationContext(jp, cfg);
result = _findRootDeserializer(ctxt, valueType).getNullValue();
} else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) {
result = null;
} else { // pointing to event other than null
DeserializationContext ctxt = createDeserializationContext(jp, cfg);
JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, valueType);
// ok, let's get the value
if (cfg.useRootWrapping()) {
result = _unwrapAndDeserialize(jp, ctxt, cfg, valueType, deser);
} else {
result = deser.deserialize(jp, ctxt);
}
}
// Need to consume the token too
jp.clearCurrentToken();
return result;
}
protected Object _readMapAndClose(JsonParser jp, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
try {
Object result;
JsonToken t = _initForReading(jp);
if (t == JsonToken.VALUE_NULL) {
// [JACKSON-643]: Ask JsonDeserializer what 'null value' to use:
DeserializationContext ctxt = createDeserializationContext(jp,
getDeserializationConfig());
result = _findRootDeserializer(ctxt, valueType).getNullValue();
} else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) {
result = null;
} else {
DeserializationConfig cfg = getDeserializationConfig();
DeserializationContext ctxt = createDeserializationContext(jp, cfg);
JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, valueType);
if (cfg.useRootWrapping()) {
result = _unwrapAndDeserialize(jp, ctxt, cfg, valueType, deser);
} else {
result = deser.
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>deserialize(jp, ctxt);
}
ctxt.checkUnresolvedObjectId();
}
// Need to consume the token too
jp.clearCurrentToken();
return result;
} finally {
try {
jp.close();
} catch (IOException ioe) { }
}
}
/**
* Method called to ensure that given parser is ready for reading
* content for data binding.
*
* @return First token to be used for data binding after this call:
* can never be null as exception will be thrown if parser can not
* provide more tokens.
*
* @throws IOException if the underlying input source has problems during
* parsing
* @throws JsonParseException if parser has problems parsing content
* @throws JsonMappingException if the parser does not have any more
* content to map (note: Json "null" value is considered content;
* enf-of-stream not)
*/
protected JsonToken _initForReading(JsonParser jp)
throws IOException, JsonParseException, JsonMappingException
{
/* First: must point to a token; if not pointing to one, advance.
* This occurs before first read from JsonParser, as well as
* after clearing of current token.
*/
JsonToken t = jp.getCurrentToken();
if (t == null) {
// and then we must get something...
t = jp.nextToken();
if (t == null) {
/* [JACKSON-546] Throw mapping exception, since it's failure to map,
* not an actual parsing problem
*/
throw JsonMappingException.from(jp, "No content to map due to end-of-input");
}
}
return t;
}
protected Object _unwrapAndDeserialize(JsonParser jp, DeserializationContext ctxt,
DeserializationConfig config,
JavaType rootType, JsonDeserializer<Object> deser)
throws IOException, JsonParseException, JsonMappingException
{
String expName = config.getRootName();
if (expName == null) {
PropertyName pname = _rootNames.findRootName(rootType, config);
expName = pname.getSimpleName();
}
if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
throw JsonMappingException.from(jp, "Current token not START_OBJECT (needed to unwrap root name '"
+expName+"'), but "+jp.getCurrentToken());
}
if (jp.nextToken() != JsonToken.FIELD_NAME) {
throw JsonMappingException.from(jp, "Current token not FIELD_NAME (to contain expected root name '"
+expName+"'), but "+jp.getCurrentToken());
}
String actualName = jp.getCurrentName();
if (!expName.equals(actualName)) {
throw JsonMappingException.from(jp, "Root name '"+actualName+"' does not match expected ('"
+expName+"') for type "+rootType);
}
// ok, then move to value itself....
jp.nextToken();
Object result = deser.deserialize(jp, ctxt);
// and last, verify that we now get matching END_OBJECT
if (jp.nextToken() != JsonToken.END_OBJECT) {
throw JsonMappingException.from(jp, "Current token not END_OBJECT (to match wrapper object with root name '"
+expName+"'), but "+jp.getCurrent
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>(AnnotatedClass ac) {
return _findFilterId(ac);
}
@Override
public Object findFilterId(Annotated a) {
return _findFilterId(a);
}
protected final Object _findFilterId(Annotated a)
{
JsonFilter ann = a.getAnnotation(JsonFilter.class);
if (ann != null) {
String id = ann.value();
// Empty String is same as not having annotation, to allow overrides
if (id.length() > 0) {
return id;
}
}
return null;
}
@Override
public Object findNamingStrategy(AnnotatedClass ac)
{
JsonNaming ann = ac.getAnnotation(JsonNaming.class);
return (ann == null) ? null : ann.value();
}
/*
/**********************************************************
/* Property auto-detection
/**********************************************************
*/
@Override
public VisibilityChecker<?> findAutoDetectVisibility(AnnotatedClass ac,
VisibilityChecker<?> checker)
{
JsonAutoDetect ann = ac.getAnnotation(JsonAutoDetect.class);
return (ann == null) ? checker : checker.with(ann);
}
/*
/**********************************************************
/* General member (field, method/constructor) annotations
/**********************************************************
*/
@Override
public ReferenceProperty findReferenceType(AnnotatedMember member)
{
JsonManagedReference ref1 = member.getAnnotation(JsonManagedReference.class);
if (ref1 != null) {
return AnnotationIntrospector.ReferenceProperty.managed(ref1.value());
}
JsonBackReference ref2 = member.getAnnotation(JsonBackReference.class);
if (ref2 != null) {
return AnnotationIntrospector.ReferenceProperty.back(ref2.value());
}
return null;
}
@Override
public NameTransformer findUnwrappingNameTransformer(AnnotatedMember member)
{
JsonUnwrapped ann = member.getAnnotation(JsonUnwrapped.class);
// if not enabled, just means annotation is not enabled; not necessarily
// that unwrapping should not be done (relevant when using chained introspectors)
if (ann == null || !ann.enabled()) {
return null;
}
String prefix = ann.prefix();
String suffix = ann.suffix();
return NameTransformer.simpleTransformer(prefix, suffix);
}
@Override
public boolean hasIgnoreMarker(AnnotatedMember m) {
return _isIgnorable(m);
}
@Override
public Boolean hasRequiredMarker(AnnotatedMember m)
{
JsonProperty ann = m.getAnnotation(JsonProperty.class);
if (ann != null) {
return ann.required();
}
return null;
}
@Override
public Object findInjectableValueId(AnnotatedMember m)
{
JacksonInject ann = m.getAnnotation(JacksonInject.class);
if (ann == null) {
return null;
}
/* Empty String means that we should use name of declared
* value class.
*/
String id = ann.value();
if (id.length() == 0) {
// slight complication; for setters, type
if (!(m instanceof AnnotatedMethod)) {
return m.getRawType().getName();
}
AnnotatedMethod am = (AnnotatedMethod) m;
if (am.getParameterCount() == 0) {
return m.getRawType().getName();
}
return am
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>.getRawParameterType(0).getName();
}
return id;
}
/*
/**********************************************************
/* Class annotations for PM type handling (1.5+)
/**********************************************************
*/
@Override
public TypeResolverBuilder<?> findTypeResolver(MapperConfig<?> config,
AnnotatedClass ac, JavaType baseType)
{
return _findTypeResolver(config, ac, baseType);
}
@Override
public TypeResolverBuilder<?> findPropertyTypeResolver(MapperConfig<?> config,
AnnotatedMember am, JavaType baseType)
{
/* As per definition of @JsonTypeInfo, should only apply to contents of container
* (collection, map) types, not container types themselves:
*/
if (baseType.isContainerType()) return null;
// No per-member type overrides (yet)
return _findTypeResolver(config, am, baseType);
}
@Override
public TypeResolverBuilder<?> findPropertyContentTypeResolver(MapperConfig<?> config,
AnnotatedMember am, JavaType containerType)
{
/* First: let's ensure property is a container type: caller should have
* verified but just to be sure
*/
if (!containerType.isContainerType()) {
throw new IllegalArgumentException("Must call method with a container type (got "+containerType+")");
}
return _findTypeResolver(config, am, containerType);
}
@Override
public List<NamedType> findSubtypes(Annotated a)
{
JsonSubTypes t = a.getAnnotation(JsonSubTypes.class);
if (t == null) return null;
JsonSubTypes.Type[] types = t.value();
ArrayList<NamedType> result = new ArrayList<NamedType>(types.length);
for (JsonSubTypes.Type type : types) {
result.add(new NamedType(type.value(), type.name()));
}
return result;
}
@Override
public String findTypeName(AnnotatedClass ac)
{
JsonTypeName tn = ac.getAnnotation(JsonTypeName.class);
return (tn == null) ? null : tn.value();
}
/*
/**********************************************************
/* Serialization: general annotations
/**********************************************************
*/
@Override
public Object findSerializer(Annotated a)
{
JsonSerialize ann = a.getAnnotation(JsonSerialize.class);
if (ann != null) {
Class<? extends JsonSerializer<?>> serClass = ann.using();
if (serClass != JsonSerializer.None.class) {
return serClass;
}
}
/* 18-Oct-2010, tatu: [JACKSON-351] @JsonRawValue handled just here, for now;
* if we need to get raw indicator from other sources need to add
* separate accessor within {@link AnnotationIntrospector} interface.
*/
JsonRawValue annRaw = a.getAnnotation(JsonRawValue.class);
if ((annRaw != null) && annRaw.value()) {
// let's construct instance with nominal type:
Class<?> cls = a.getRawType();
return new RawSerializer<Object>(cls);
}
return null;
}
@Override
public Class<? extends JsonSerializer<?>> findKeySerializer(Annotated a)
{
JsonSerialize ann = a.getAnnotation(JsonSerialize.class);
if (ann != null) {
Class<? extends JsonSerializer<?>> serClass = ann
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>Exception e) {
if (cause != null) {
cause.set(e);
}
} catch (RuntimeException e) {
if (cause == null) { // earlier behavior
throw e;
}
cause.set(e);
}
return false;
}
/**
* Method for finding a value deserializer, and creating a contextual
* version if necessary, for value reached via specified property.
*/
@SuppressWarnings("unchecked")
public final JsonDeserializer<Object> findContextualValueDeserializer(JavaType type,
BeanProperty prop) throws JsonMappingException
{
JsonDeserializer<Object> deser = _cache.findValueDeserializer(this, _factory, type);
if (deser != null) {
deser = (JsonDeserializer<Object>) handleSecondaryContextualization(deser, prop);
}
return deser;
}
/**
* Method for finding a deserializer for root-level value.
*/
@SuppressWarnings("unchecked")
public final JsonDeserializer<Object> findRootValueDeserializer(JavaType type)
throws JsonMappingException
{
JsonDeserializer<Object> deser = _cache.findValueDeserializer(this,
_factory, type);
if (deser == null) { // can this occur?
return null;
}
deser = (JsonDeserializer<Object>) handleSecondaryContextualization(deser, null);
TypeDeserializer typeDeser = _factory.findTypeDeserializer(_config, type);
if (typeDeser != null) {
// important: contextualize to indicate this is for root value
typeDeser = typeDeser.forProperty(null);
return new TypeWrappedDeserializer(typeDeser, deser);
}
return deser;
}
/**
* Convenience method, functionally same as:
*<pre>
* getDeserializerProvider().findKeyDeserializer(getConfig(), prop.getType(), prop);
*</pre>
*/
public final KeyDeserializer findKeyDeserializer(JavaType keyType,
BeanProperty prop) throws JsonMappingException {
KeyDeserializer kd = _cache.findKeyDeserializer(this,
_factory, keyType);
// Second: contextualize?
if (kd instanceof ContextualKeyDeserializer) {
kd = ((ContextualKeyDeserializer) kd).createContextual(this, prop);
}
return kd;
}
/*
/**********************************************************
/* Public API, ObjectId handling
/**********************************************************
*/
/**
* Method called to find and return entry corresponding to given
* Object Id: will add an entry if necessary, and never returns null
*/
public abstract ReadableObjectId findObjectId(Object id, ObjectIdGenerator<?> generator, ObjectIdResolver resolver);
@Deprecated // since 2.4
public abstract ReadableObjectId findObjectId(Object id, ObjectIdGenerator<?> generator);
/**
* Method called to ensure that every object id encounter during processing
* are resolved.
*
* @throws UnresolvedForwardReference
*/
public abstract void checkUnresolvedObjectId()
throws UnresolvedForwardReference;
/*
/**********************************************************
/* Public API, type handling
/**********************************************************
*/
/**
* Convenience method, functionally equivalent to:
*<pre>
* getConfig().constructType(cls);
* </pre>
*/
public final JavaType constructType(Class<?> cls) {
return _config.constructType(cls);
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> that the property (passed to this method -- usually property that
* has custom serializer that called this method) has.
*
* @since 2.4
*/
public <T> T readPropertyValue(JsonParser p, BeanProperty prop, Class<T> type) throws IOException {
return readPropertyValue(p, prop, getTypeFactory().constructType(type));
}
/**
* @since 2.4
*/
@SuppressWarnings("unchecked")
public <T> T readPropertyValue(JsonParser p, BeanProperty prop, JavaType type) throws IOException {
JsonDeserializer<Object> deser = findContextualValueDeserializer(type, prop);
if (deser == null) {
}
return (T) deser.deserialize(p, this);
}
/*
/**********************************************************
/* Methods for problem handling, reporting
/**********************************************************
*/
/**
* Method deserializers can call to inform configured {@link DeserializationProblemHandler}s
* of an unrecognized property.
*
* @return True if there was a configured problem handler that was able to handle the
* problem
*/
/**
* Method deserializers can call to inform configured {@link DeserializationProblemHandler}s
* of an unrecognized property.
*/
public boolean handleUnknownProperty(JsonParser p, JsonDeserializer<?> deser,
Object instanceOrClass, String propName)
throws IOException, JsonProcessingException
{
LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
if (h != null) {
while (h != null) {
// Can bail out if it's handled
if (h.value().handleUnknownProperty(this, p, deser, instanceOrClass, propName)) {
return true;
}
h = h.next();
}
}
return false;
}
/**
* Helper method for reporting a problem with unhandled unknown exception
*
* @param instanceOrClass Either value being populated (if one has been
* instantiated), or Class that indicates type that would be (or
* have been) instantiated
* @param deser Deserializer that had the problem, if called by deserializer
* (or on behalf of one)
*/
public void reportUnknownProperty(Object instanceOrClass, String fieldName,
JsonDeserializer<?> deser)
throws JsonMappingException
{
if (!isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) {
return;
}
// Do we know properties that are expected instead?
Collection<Object> propIds = (deser == null) ? null : deser.getKnownPropertyNames();
throw UnrecognizedPropertyException.from(_parser,
instanceOrClass, fieldName, propIds);
}
/*
/**********************************************************
/* Methods for constructing exceptions
/**********************************************************
*/
/**
* Helper method for constructing generic mapping exception for specified type
*/
public JsonMappingException mappingException(Class<?> targetClass) {
return mappingException(targetClass, _parser.getCurrentToken());
}
public JsonMappingException mappingException(Class<?> targetClass, JsonToken token) {
return JsonMappingException.from(_parser, "Can not deserialize instance of "+_calcName(targetClass)+" out of "+token+" token");
}
/**
* Helper method for constructing generic mapping exception with specified
* message and current location information
*/
public JsonMappingException mappingException(String message) {
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> return JsonMappingException.from(getParser(), message);
}
/**
* Helper method for constructing instantiation exception for specified type,
* to indicate problem with physically constructing instance of
* specified class (missing constructor, exception from constructor)
*/
public JsonMappingException instantiationException(Class<?> instClass, Throwable t) {
return JsonMappingException.from(_parser,
"Can not construct instance of "+instClass.getName()+", problem: "+t.getMessage(), t);
}
public JsonMappingException instantiationException(Class<?> instClass, String msg) {
return JsonMappingException.from(_parser, "Can not construct instance of "+instClass.getName()+", problem: "+msg);
}
/**
* Method that will construct an exception suitable for throwing when
* some String values are acceptable, but the one encountered is not.
*
*
* @deprecated Since 2.1 should use variant that takes value
*/
@Deprecated
public JsonMappingException weirdStringException(Class<?> instClass, String msg) {
return weirdStringException(null, instClass, msg);
}
/**
* Method that will construct an exception suitable for throwing when
* some String values are acceptable, but the one encountered is not.
*
* @param value String value from input being deserialized
* @param instClass Type that String should be deserialized into
* @param msg Message that describes specific problem
*
* @since 2.1
*/
public JsonMappingException weirdStringException(String value, Class<?> instClass, String msg) {
return InvalidFormatException.from(_parser,
"Can not construct instance of "+instClass.getName()+" from String value '"+_valueDesc()+"': "+msg,
value, instClass);
}
/**
* Helper method for constructing exception to indicate that input JSON
* Number was not suitable for deserializing into given type.
*/
@Deprecated
public JsonMappingException weirdNumberException(Class<?> instClass, String msg) {
return weirdStringException(null, instClass, msg);
}
/**
* Helper method for constructing exception to indicate that input JSON
* Number was not suitable for deserializing into given target type.
*/
public JsonMappingException weirdNumberException(Number value, Class<?> instClass, String msg) {
return InvalidFormatException.from(_parser,
"Can not construct instance of "+instClass.getName()+" from number value ("+_valueDesc()+"): "+msg,
null, instClass);
}
/**
* Helper method for constructing exception to indicate that given JSON
* Object field name was not in format to be able to deserialize specified
* key type.
*/
public JsonMappingException weirdKeyException(Class<?> keyClass, String keyValue, String msg) {
return InvalidFormatException.from(_parser,
"Can not construct Map key of type "+keyClass.getName()+" from String \""+_desc(keyValue)+"\": "+msg,
keyValue, keyClass);
}
/**
* Helper method for indicating that the current token was expected to be another
* token.
*/
public JsonMappingException wrongTokenException(JsonParser p, JsonToken expToken, String msg0) {
String msg = "Unexpected token ("+p.getCurrentToken()+"), expected "+expToken;
if (msg0 != null) {
msg = msg + ": "+msg0;
}
return JsonMappingException.from
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>(p, msg);
}
/**
* Helper method for constructing exception to indicate that given
* type id (parsed from JSON) could not be converted to a Java type.
*/
public JsonMappingException unknownTypeException(JavaType type, String id) {
return JsonMappingException.from(_parser, "Could not resolve type id '"+id+"' into a subtype of "+type);
}
public JsonMappingException endOfInputException(Class<?> instClass) {
return JsonMappingException.from(_parser, "Unexpected end-of-input when trying to deserialize a "
+instClass.getName());
}
/*
/**********************************************************
/* Overridable internal methods
/**********************************************************
*/
protected DateFormat getDateFormat()
{
if (_dateFormat != null) {
return _dateFormat;
}
/* 24-Feb-2012, tatu: At this point, all timezone configuration
* should have occured, with respect to default dateformat
* and timezone configuration. But we still better clone
* an instance as formatters may be stateful.
*/
DateFormat df = _config.getDateFormat();
_dateFormat = df = (DateFormat) df.clone();
return df;
}
protected String determineClassName(Object instance) {
return ClassUtil.getClassDescription(instance);
}
/*
/**********************************************************
/* Other internal methods
/**********************************************************
*/
protected String _calcName(Class<?> cls) {
if (cls.isArray()) {
return _calcName(cls.getComponentType())+"[]";
}
return cls.getName();
}
protected String _valueDesc() {
try {
return _desc(_parser.getText());
} catch (Exception e) {
return "[N/A]";
}
}
protected String _desc(String desc) {
// !!! should we quote it? (in case there are control chars, linefeeds)
if (desc.length() > MAX_ERROR_STR_LEN) {
desc = desc.substring(0, MAX_ERROR_STR_LEN) + "]...[" + desc.substring(desc.length() - MAX_ERROR_STR_LEN);
}
return desc;
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.util.Arrays;
import java.util.UUID;
import com.fasterxml.jackson.core.Base64Variants;
import com.fasterxml.jackson.databind.DeserializationContext;
public class UUIDDeserializer extends FromStringDeserializer<UUID>
{
private static final long serialVersionUID = 1L;
final static int[] HEX_DIGITS = new int[127];
static {
Arrays.fill(HEX_DIGITS, -1);
for (int i = 0; i < 10; ++i) { HEX_DIGITS['0' + i] = i; }
for (int i = 0; i < 6; ++i) {
HEX_DIGITS['a' + i] = 10 + i;
HEX_DIGITS['A' + i] = 10 + i;
}
}
public UUIDDeserializer() { super(UUID.class); }
@Override
protected UUID _deserialize(String id, DeserializationContext ctxt) throws IOException
{
// Adapted from java-uuid-generator (https://github.com/cowtowncoder/java-uuid-generator)
// which is 5x faster than UUID.fromString(value), as oper "ManualReadPerfWithUUID"
if (id.length() != 36) {
/* 14-Sep-2013, tatu: One trick we do allow, Base64-encoding, since we know
* length it must have...
*/
if (id.length() == 24) {
byte[] stuff = Base64Variants.getDefaultVariant().decode(id);
return _fromBytes(stuff, ctxt);
}
_badFormat(id);
}
// verify hyphens first:
if ((id.charAt(8) != '-') || (id.charAt(13) != '-')
|| (id.charAt(18) != '-') || (id.charAt(23) != '-')) {
_badFormat(id);
}
long l1 = intFromChars(id, 0);
l1 <<= 32;
long l2 = ((long) shortFromChars(id, 9)) << 16;
l2 |= shortFromChars(id, 14);
long hi = l1 + l2;
int i1 = (shortFromChars(id, 19) << 16) | shortFromChars(id, 24);
l1 = i1;
l1 <<= 32;
l2 = intFromChars(id, 28);
l2 = (l2 << 32) >>> 32; // sign removal, Java-style. Ugh.
long lo = l1 | l2;
return new UUID(hi, lo);
}
@Override
protected UUID _deserializeEmbedded(Object ob, DeserializationContext ctxt) throws IOException
{
if (ob instanceof byte[]) {
return _fromBytes((byte[]) ob, ctxt);
}
super._deserializeEmbedded(ob, ctxt);
return null; // never gets here
}
private void _badFormat(String uuidStr) {
throw new NumberFormatException("UUID has to be represented by the
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> standard 36-char representation");
}
static int intFromChars(String str, int index) {
return (byteFromChars(str, index) << 24) + (byteFromChars(str, index+2) << 16) + (byteFromChars(str, index+4) << 8) + byteFromChars(str, index+6);
}
static int shortFromChars(String str, int index) {
return (byteFromChars(str, index) << 8) + byteFromChars(str, index+2);
}
static int byteFromChars(String str, int index)
{
final char c1 = str.charAt(index);
final char c2 = str.charAt(index+1);
if (c1 <= 127 && c2 <= 127) {
int hex = (HEX_DIGITS[c1] << 4) | HEX_DIGITS[c2];
if (hex >= 0) {
return hex;
}
}
if (c1 > 127 || HEX_DIGITS[c1] < 0) {
return _badChar(str, index, c1);
}
return _badChar(str, index+1, c2);
}
static int _badChar(String uuidStr, int index, char c) {
throw new NumberFormatException("Non-hex character '"+c+"', not valid character for a UUID String"
+"' (value 0x"+Integer.toHexString(c)+") for UUID String \""+uuidStr+"\"");
}
private UUID _fromBytes(byte[] bytes, DeserializationContext ctxt) throws IOException {
if (bytes.length != 16) {
ctxt.mappingException("Can only construct UUIDs from byte[16]; got "+bytes.length+" bytes");
}
return new UUID(_long(bytes, 0), _long(bytes, 8));
}
private static long _long(byte[] b, int offset) {
long l1 = ((long) _int(b, offset)) << 32;
long l2 = _int(b, offset+4);
// faster to just do it than check if it has sign
l2 = (l2 << 32) >>> 32; // to get rid of sign
return l1 | l2;
}
private static int _int(byte[] b, int offset) {
return (b[offset] << 24) | ((b[offset+1] & 0xFF) << 16) | ((b[offset+2] & 0xFF) << 8) | (b[offset+3] & 0xFF);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializable;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
/**
* Abstract base class common to all standard {@link JsonNode}
* implementations.
* The main addition here is that we declare that sub-classes must
* implement {@link JsonSerializable}.
* This simplifies object mapping aspects a bit, as no external serializers are needed.
*/
public abstract class BaseJsonNode
extends JsonNode
implements JsonSerializable
{
protected BaseJsonNode() { }
/*
/**********************************************************
/* Basic definitions for non-container types
/**********************************************************
*/
@Override
public final JsonNode findPath(String fieldName)
{
JsonNode value = findValue(fieldName);
if (value == null) {
return MissingNode.getInstance();
}
return value;
}
/*
/**********************************************************
/* Support for traversal-as-stream
/**********************************************************
*/
@Override
public JsonParser traverse() {
return new TreeTraversingParser(this);
}
@Override
public JsonParser traverse(ObjectCodec codec) {
return new TreeTraversingParser(this, codec);
}
/**
* Method that can be used for efficient type detection
* when using stream abstraction for traversing nodes.
* Will return the first {@link JsonToken} that equivalent
* stream event would produce (for most nodes there is just
* one token but for structured/container types multiple)
*/
@Override
public abstract JsonToken asToken();
/**
* Returns code that identifies type of underlying numeric
* value, if (and only if) node is a number node.
*/
@Override
public JsonParser.NumberType numberType() {
// most types non-numeric, so:
return null;
}
/*
/**********************************************************
/* JsonSerializable
/**********************************************************
*/
/**
* Method called to serialize node instances using given generator.
*/
@Override
public abstract void serialize(JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException;
/**
* Type information is needed, even if JsonNode instances are "plain" JSON,
* since they may be mixed with other types.
*/
@Override
public abstract void serializeWithType(JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer)
throws IOException, JsonProcessingException;
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.impl;
import java.io.IOException;
import java.util.HashSet;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.*;
import com.fasterxml.jackson.databind.util.NameTransformer;
/**
* Variant of {@link BeanDeserializer} used for handling deserialization
* of POJOs when serialized as JSON Arrays, instead of JSON Objects.
*
* @since 2.1
*/
public class BeanAsArrayDeserializer
extends BeanDeserializerBase
{
private static final long serialVersionUID = 1L;
/**
* Deserializer we delegate operations that we can not handle.
*/
protected final BeanDeserializerBase _delegate;
/**
* Properties in order expected to be found in JSON array.
*/
protected final SettableBeanProperty[] _orderedProperties;
/*
/**********************************************************
/* Life-cycle, construction, initialization
/**********************************************************
*/
/**
* Main constructor used both for creating new instances (by
* {@link BeanDeserializer#asArrayDeserializer}) and for
* creating copies with different delegate.
*/
public BeanAsArrayDeserializer(BeanDeserializerBase delegate,
SettableBeanProperty[] ordered)
{
super(delegate);
_delegate = delegate;
_orderedProperties = ordered;
}
@Override
public JsonDeserializer<Object> unwrappingDeserializer(NameTransformer unwrapper)
{
/* We can't do much about this; could either replace _delegate
* with unwrapping instance, or just replace this one. Latter seems
* more sensible.
*/
return _delegate.unwrappingDeserializer(unwrapper);
}
@Override
public BeanAsArrayDeserializer withObjectIdReader(ObjectIdReader oir) {
return new BeanAsArrayDeserializer(_delegate.withObjectIdReader(oir),
_orderedProperties);
}
@Override
public BeanAsArrayDeserializer withIgnorableProperties(HashSet<String> ignorableProps) {
return new BeanAsArrayDeserializer(_delegate.withIgnorableProperties(ignorableProps),
_orderedProperties);
}
@Override
protected BeanDeserializerBase asArrayDeserializer() {
return this;
}
/*
/**********************************************************
/* JsonDeserializer implementation
/**********************************************************
*/
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// Let's delegate just in case we got a JSON Object (could error out, alternatively?)
if (jp.getCurrentToken() != JsonToken.START_ARRAY) {
return _deserializeFromNonArray(jp, ctxt);
}
if (!_vanillaProcessing) {
return _deserializeNonVanilla(jp, ctxt);
}
final Object bean = _valueInstantiator.createUsingDefault(ctxt);
final SettableBeanProperty[] props = _orderedProperties;
int i = 0;
final int propCount = props.length;
while (true) {
if (jp.nextToken() == JsonToken.END_ARRAY) {
return bean;
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> }
if (i == propCount) {
break;
}
SettableBeanProperty prop = props[i];
if (prop != null) { // normal case
try {
prop.deserializeAndSet(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, prop.getName(), ctxt);
}
} else { // just skip?
jp.skipChildren();
}
++i;
}
// Ok; extra fields? Let's fail, unless ignoring extra props is fine
if (!_ignoreAllUnknown) {
throw ctxt.mappingException("Unexpected JSON values; expected at most "+propCount+" properties (in JSON Array)");
}
// otherwise, skip until end
while (jp.nextToken() != JsonToken.END_ARRAY) {
jp.skipChildren();
}
return bean;
}
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt, Object bean)
throws IOException, JsonProcessingException
{
/* No good way to verify that we have an array... although could I guess
* check via JsonParser. So let's assume everything is working fine, for now.
*/
if (_injectables != null) {
injectValues(ctxt, bean);
}
final SettableBeanProperty[] props = _orderedProperties;
int i = 0;
final int propCount = props.length;
while (true) {
if (jp.nextToken() == JsonToken.END_ARRAY) {
return bean;
}
if (i == propCount) {
break;
}
SettableBeanProperty prop = props[i];
if (prop != null) { // normal case
try {
prop.deserializeAndSet(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, prop.getName(), ctxt);
}
} else { // just skip?
jp.skipChildren();
}
++i;
}
// Ok; extra fields? Let's fail, unless ignoring extra props is fine
if (!_ignoreAllUnknown) {
throw ctxt.mappingException("Unexpected JSON values; expected at most "+propCount+" properties (in JSON Array)");
}
// otherwise, skip until end
while (jp.nextToken() != JsonToken.END_ARRAY) {
jp.skipChildren();
}
return bean;
}
// needed since 2.1
@Override
public Object deserializeFromObject(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
return _deserializeFromNonArray(jp, ctxt);
}
/*
/**********************************************************
/* Helper methods, non-standard creation
/**********************************************************
*/
/**
* Alternate deserialization method that has to check many more configuration
* aspects than the "vanilla" processing.
*/
protected Object _deserializeNonVanilla(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (_nonStandardCreation) {
return _deserializeWithCreator(jp, ctxt);
}
final Object bean = _valueInstantiator.createUsingDefault(ctxt);
if (_injectables != null) {
injectValues(ctxt, bean);
}
Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
final SettableBeanProperty[] props = _orderedProperties;
int i
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> = 0;
final int propCount = props.length;
while (true) {
if (jp.nextToken() == JsonToken.END_ARRAY) {
return bean;
}
if (i == propCount) {
break;
}
SettableBeanProperty prop = props[i];
++i;
if (prop != null) { // normal case
if (activeView == null || prop.visibleInView(activeView)) {
try {
prop.deserializeAndSet(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, prop.getName(), ctxt);
}
continue;
}
}
// otherwise, skip it (view-filtered, no prop etc)
jp.skipChildren();
}
// Ok; extra fields? Let's fail, unless ignoring extra props is fine
if (!_ignoreAllUnknown) {
throw ctxt.mappingException("Unexpected JSON values; expected at most "+propCount+" properties (in JSON Array)");
}
// otherwise, skip until end
while (jp.nextToken() != JsonToken.END_ARRAY) {
jp.skipChildren();
}
return bean;
}
protected Object _deserializeWithCreator(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (_delegateDeserializer != null) {
return _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt));
}
if (_propertyBasedCreator != null) {
return _deserializeUsingPropertyBased(jp, ctxt);
}
// should only occur for abstract types...
if (_beanType.isAbstract()) {
throw JsonMappingException.from(jp, "Can not instantiate abstract type "+_beanType
+" (need to add/enable type information?)");
}
throw JsonMappingException.from(jp, "No suitable constructor found for type "
+_beanType+": can not instantiate from JSON object (need to add/enable type information?)");
}
/**
* Method called to deserialize bean using "property-based creator":
* this means that a non-default constructor or factory method is
* called, and then possibly other setters. The trick is that
* values for creator method need to be buffered, first; and
* due to non-guaranteed ordering possibly some other properties
* as well.
*/
@Override
protected final Object _deserializeUsingPropertyBased(final JsonParser jp, final DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
final PropertyBasedCreator creator = _propertyBasedCreator;
PropertyValueBuffer buffer = creator.startBuilding(jp, ctxt, _objectIdReader);
final SettableBeanProperty[] props = _orderedProperties;
final int propCount = props.length;
int i = 0;
Object bean = null;
for (; jp.nextToken() != JsonToken.END_ARRAY; ++i) {
SettableBeanProperty prop = (i < propCount) ? props[i] : null;
if (prop == null) { // we get null if there are extra elements; maybe otherwise too?
jp.skipChildren();
continue;
}
// if we have already constructed POJO, things are simple:
if (bean != null) {
try {
prop.deserializeAndSet(jp, ctxt, bean);
} catch (Exception e) {
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> wrapAndThrow(e, bean, prop.getName(), ctxt);
}
continue;
}
final String propName = prop.getName();
// if not yet, maybe we got a creator property?
SettableBeanProperty creatorProp = creator.findCreatorProperty(propName);
if (creatorProp != null) {
// Last creator property to set?
Object value = creatorProp.deserialize(jp, ctxt);
if (buffer.assignParameter(creatorProp.getCreatorIndex(), value)) {
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
continue; // never gets here
}
// polymorphic?
if (bean.getClass() != _beanType.getRawClass()) {
/* 23-Jul-2012, tatu: Not sure if these could ever be properly
* supported (since ordering of elements may not be guaranteed);
* but make explicitly non-supported for now.
*/
throw ctxt.mappingException("Can not support implicit polymorphic deserialization for POJOs-as-Arrays style: "
+"nominal type "+_beanType.getRawClass().getName()+", actual type "+bean.getClass().getName());
}
}
continue;
}
// Object Id property?
if (buffer.readIdProperty(propName)) {
continue;
}
// regular property? needs buffering
buffer.bufferProperty(prop, prop.deserialize(jp, ctxt));
}
// In case we didn't quite get all the creator properties, we may have to do this:
if (bean == null) {
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
return null; // never gets here
}
}
return bean;
}
/*
/**********************************************************
/* Helper methods, error reporting
/**********************************************************
*/
protected Object _deserializeFromNonArray(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// Let's start with failure
throw ctxt.mappingException("Can not deserialize a POJO (of type "+_beanType.getRawClass().getName()
+") from non-Array representation (token: "+jp.getCurrentToken()
+"): type/property designed to be serialized as JSON Array");
// in future, may allow use of "standard" POJO serialization as well; if so, do:
//return _delegate.deserialize(jp, ctxt);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
return new EnumMapSerializer(_valueType, _staticTyping, _keyEnums, vts, _valueSerializer);
}
public EnumMapSerializer withValueSerializer(BeanProperty prop, JsonSerializer<?> ser) {
if (_property == prop && ser == _valueSerializer) {
return this;
}
return new EnumMapSerializer(this, prop, ser);
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider provider,
BeanProperty property)
throws JsonMappingException
{
/* 29-Sep-2012, tatu: Actually, we need to do much more contextual
* checking here since we finally know for sure the property,
* and it may have overrides
*/
JsonSerializer<?> ser = null;
// First: if we have a property, may have property-annotation overrides
if (property != null) {
AnnotatedMember m = property.getMember();
if (m != null) {
Object serDef = provider.getAnnotationIntrospector().findContentSerializer(m);
if (serDef != null) {
ser = provider.serializerInstance(m, serDef);
}
}
}
if (ser == null) {
ser = _valueSerializer;
}
// #124: May have a content converter
ser = findConvertingContentSerializer(provider, property, ser);
if (ser == null) {
if (_staticTyping) {
return withValueSerializer(property, provider.findValueSerializer(_valueType, property));
}
} else {
ser = provider.handleSecondaryContextualization(ser, property);
}
if (ser != _valueSerializer) {
return withValueSerializer(property, ser);
}
return this;
}
/*
/**********************************************************
/* Accessors
/**********************************************************
*/
@Override
public JavaType getContentType() {
return _valueType;
}
@Override
public JsonSerializer<?> getContentSerializer() {
return _valueSerializer;
}
@Override
public boolean isEmpty(EnumMap<? extends Enum<?>,?> value) {
return (value == null) || value.isEmpty();
}
@Override
public boolean hasSingleElement(EnumMap<? extends Enum<?>, ?> value) {
return value.size() == 1;
}
/*
/**********************************************************
/* Serialization
/**********************************************************
*/
@Override
public void serialize(EnumMap<? extends Enum<?>,?> value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
jgen.writeStartObject();
if (!value.isEmpty()) {
serializeContents(value, jgen, provider);
}
jgen.writeEndObject();
}
@Override
public void serializeWithType(EnumMap<? extends Enum<?>,?> value, JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer)
throws IOException, JsonGenerationException
{
typeSer.writeTypePrefixForObject(value, jgen);
if (!value.isEmpty()) {
serializeContents(value, jgen, provider);
}
typeSer.writeTypeSuffixForObject(value, jgen);
}
protected void serializeContents(EnumMap<? extends Enum<?>,?> value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
if (_valueSerializer != null) {
serializeContentsUsing(value, j
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.Type;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
public abstract class StdScalarSerializer<T>
extends StdSerializer<T>
{
protected StdScalarSerializer(Class<T> t) {
super(t);
}
/**
* Alternate constructor that is (alas!) needed to work
* around kinks of generic type handling
*/
@SuppressWarnings("unchecked")
protected StdScalarSerializer(Class<?> t, boolean dummy) {
super((Class<T>) t);
}
/**
* Default implementation will write type prefix, call regular serialization
* method (since assumption is that value itself does not need JSON
* Array or Object start/end markers), and then write type suffix.
* This should work for most cases; some sub-classes may want to
* change this behavior.
*/
@Override
public void serializeWithType(T value, JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer)
throws IOException, JsonGenerationException
{
typeSer.writeTypePrefixForScalar(value, jgen);
serialize(value, jgen, provider);
typeSer.writeTypeSuffixForScalar(value, jgen);
}
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
throws JsonMappingException
{
return createSchemaNode("string", true);
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
if (visitor != null) {
// 13-Sep-2013, tatu: Let's assume it's usually a String, right?
// visitor.expectAnyFormat(typeHint);
visitor.expectStringFormat(typeHint);
}
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Member;
import java.lang.reflect.Type;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
/**
* Object that represents method parameters, mostly so that associated
* annotations can be processed conveniently. Note that many of accessors
* can not return meaningful values since parameters do not have stand-alone
* JDK objects associated; so access should mostly be limited to checking
* annotation values which are properly aggregated and included.
*/
public final class AnnotatedParameter
extends AnnotatedMember
{
private static final long serialVersionUID = 1L;
/**
* Member (method, constructor) that this parameter belongs to
*/
protected final AnnotatedWithParams _owner;
/**
* JDK type of the parameter, possibly contains generic type information
*/
protected final Type _type;
/**
* Index of the parameter within argument list
*/
protected final int _index;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public AnnotatedParameter(AnnotatedWithParams owner, Type type, AnnotationMap annotations,
int index)
{
super(annotations);
_owner = owner;
_type = type;
_index = index;
}
@Override
public AnnotatedParameter withAnnotations(AnnotationMap ann) {
if (ann == _annotations) {
return this;
}
return _owner.replaceParameterAnnotations(_index, ann);
}
/*
/**********************************************************
/* Annotated impl
/**********************************************************
*/
/**
* Since there is no matching JDK element, this method will
* always return null
*/
@Override
public AnnotatedElement getAnnotated() { return null; }
/**
* Returns modifiers of the constructor, as parameters do not
* have independent modifiers.
*/
@Override
public int getModifiers() { return _owner.getModifiers(); }
/**
* Parameters have no names in bytecode (unlike in source code),
* will always return empty String ("").
*/
@Override
public String getName() { return ""; }
/**
* Accessor for annotations; all annotations associated with parameters
* are properly passed and accessible.
*/
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls)
{
return (_annotations == null) ? null : _annotations.get(acls);
}
@Override
public Type getGenericType() {
return _type;
}
@Override
public Class<?> getRawType()
{
if (_type instanceof Class<?>) {
return (Class<?>) _type;
}
// 14-Mar-2011, tatu: Not optimal, but has to do for now...
JavaType t = TypeFactory.defaultInstance().constructType(_type);
return t.getRawClass();
}
/*
/**********************************************************
/* AnnotatedMember extras
/**********************************************************
*/
@Override
public Class<?> getDeclaringClass() {
return _owner.getDeclaringClass();
}
@Override
public Member getMember() {
/* This is bit tricky: since there is no JDK equivalent; can either
* return null
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* Numeric node that contains simple 64-bit integer values.
*/
public class BigIntegerNode
extends NumericNode
{
private final static BigInteger MIN_INTEGER = BigInteger.valueOf(Integer.MIN_VALUE);
private final static BigInteger MAX_INTEGER = BigInteger.valueOf(Integer.MAX_VALUE);
private final static BigInteger MIN_LONG = BigInteger.valueOf(Long.MIN_VALUE);
private final static BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE);
final protected BigInteger _value;
/*
/**********************************************************
/* Construction
/**********************************************************
*/
public BigIntegerNode(BigInteger v) { _value = v; }
public static BigIntegerNode valueOf(BigInteger v) { return new BigIntegerNode(v); }
/*
/**********************************************************
/* Overrridden JsonNode methods
/**********************************************************
*/
@Override
public JsonToken asToken() { return JsonToken.VALUE_NUMBER_INT; }
@Override
public JsonParser.NumberType numberType() { return JsonParser.NumberType.BIG_INTEGER; }
@Override
public boolean isIntegralNumber() { return true; }
@Override
public boolean isBigInteger() { return true; }
@Override public boolean canConvertToInt() {
return (_value.compareTo(MIN_INTEGER) >= 0) && (_value.compareTo(MAX_INTEGER) <= 0);
}
@Override public boolean canConvertToLong() {
return (_value.compareTo(MIN_LONG) >= 0) && (_value.compareTo(MAX_LONG) <= 0);
}
@Override
public Number numberValue() {
return _value;
}
@Override
public short shortValue() { return _value.shortValue(); }
@Override
public int intValue() { return _value.intValue(); }
@Override
public long longValue() { return _value.longValue(); }
@Override
public BigInteger bigIntegerValue() { return _value; }
@Override
public float floatValue() { return _value.floatValue(); }
@Override
public double doubleValue() { return _value.doubleValue(); }
@Override
public BigDecimal decimalValue() { return new BigDecimal(_value); }
/*
/**********************************************************
/* General type coercions
/**********************************************************
*/
@Override
public String asText() {
return _value.toString();
}
@Override
public boolean asBoolean(boolean defaultValue) {
return !BigInteger.ZERO.equals(_value);
}
@Override
public final void serialize(JsonGenerator jg, SerializerProvider provider)
throws IOException, JsonProcessingException
{
jg.writeNumber(_value);
}
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof BigIntegerNode)) {
return false;
}
return ((BigIntegerNode) o)._value.equals(_value);
}
@Override
public int hashCode() {
return _value.hashCode();
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitable;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsonschema.SchemaAware;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.PropertyFilter;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.Converter;
/**
* Base class used by all standard serializers, and can also
* be used for custom serializers (in fact, this is the recommended
* base class to use).
* Provides convenience methods for implementing {@link SchemaAware}
*/
public abstract class StdSerializer<T>
extends JsonSerializer<T>
implements JsonFormatVisitable, SchemaAware
{
/**
* Nominal type supported, usually declared type of
* property for which serializer is used.
*/
protected final Class<T> _handledType;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
protected StdSerializer(Class<T> t) {
_handledType = t;
}
@SuppressWarnings("unchecked")
protected StdSerializer(JavaType type) {
_handledType = (Class<T>) type.getRawClass();
}
/**
* Alternate constructor that is (alas!) needed to work
* around kinks of generic type handling
*/
@SuppressWarnings("unchecked")
protected StdSerializer(Class<?> t, boolean dummy) {
_handledType = (Class<T>) t;
}
/*
/**********************************************************
/* Accessors
/**********************************************************
*/
@Override
public Class<T> handledType() { return _handledType; }
/*
/**********************************************************
/* Serialization
/**********************************************************
*/
@Override
public abstract void serialize(T value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException;
/*
/**********************************************************
/* Helper methods for JSON Schema generation
/**********************************************************
*/
/**
* Default implementation simply claims type is "string"; usually
* overriden by custom serializers.
*/
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
throws JsonMappingException
{
return createSchemaNode("string");
}
/**
* Default implementation simply claims type is "string"; usually
* overriden by custom serializers.
*/
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint, boolean isOptional)
throws JsonMappingException
{
ObjectNode schema = (ObjectNode) getSchema(provider, typeHint);
if (!isOptional) {
schema.put("required", !isOptional);
}
return schema;
}
protected ObjectNode createObjectNode() {
return JsonNode
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>Factory.instance.objectNode();
}
protected ObjectNode createSchemaNode(String type)
{
ObjectNode schema = createObjectNode();
schema.put("type", type);
return schema;
}
protected ObjectNode createSchemaNode(String type, boolean isOptional)
{
ObjectNode schema = createSchemaNode(type);
// as per [JACKSON-563]. Note that 'required' defaults to false
if (!isOptional) {
schema.put("required", !isOptional);
}
return schema;
}
/**
* Default implementation specifies no format. This behavior is usually
* overriden by custom serializers.
*/
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
visitor.expectAnyFormat(typeHint);
}
/*
/**********************************************************
/* Helper methods for exception handling
/**********************************************************
*/
/**
* Method that will modify caught exception (passed in as argument)
* as necessary to include reference information, and to ensure it
* is a subtype of {@link IOException}, or an unchecked exception.
*<p>
* Rules for wrapping and unwrapping are bit complicated; essentially:
*<ul>
* <li>Errors are to be passed as is (if uncovered via unwrapping)
* <li>"Plain" IOExceptions (ones that are not of type
* {@link JsonMappingException} are to be passed as is
*</ul>
*/
public void wrapAndThrow(SerializerProvider provider,
Throwable t, Object bean, String fieldName)
throws IOException
{
/* 05-Mar-2009, tatu: But one nasty edge is when we get
* StackOverflow: usually due to infinite loop. But that
* usually gets hidden within an InvocationTargetException...
*/
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors and "plain" IOExceptions to be passed as is
if (t instanceof Error) {
throw (Error) t;
}
// Ditto for IOExceptions... except for mapping exceptions!
boolean wrap = (provider == null) || provider.isEnabled(SerializationFeature.WRAP_EXCEPTIONS);
if (t instanceof IOException) {
if (!wrap || !(t instanceof JsonMappingException)) {
throw (IOException) t;
}
} else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
}
// [JACKSON-55] Need to add reference information
throw JsonMappingException.wrapWithPath(t, bean, fieldName);
}
public void wrapAndThrow(SerializerProvider provider,
Throwable t, Object bean, int index)
throws IOException
{
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors are to be passed as is
if (t instanceof Error) {
throw (Error) t;
}
// Ditto for IOExceptions... except for mapping exceptions!
boolean wrap = (provider == null) || provider.isEnabled(SerializationFeature.WRAP_EXCEPTIONS);
if (t instanceof IOException) {
if (!wrap
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> || !(t instanceof JsonMappingException)) {
throw (IOException) t;
}
} else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
}
// [JACKSON-55] Need to add reference information
throw JsonMappingException.wrapWithPath(t, bean, index);
}
/*
/**********************************************************
/* Helper methods, other
/**********************************************************
*/
/**
* Method that can be called to determine if given serializer is the default
* serializer Jackson uses; as opposed to a custom serializer installed by
* a module or calling application. Determination is done using
* {@link JacksonStdImpl} annotation on serializer class.
*/
protected boolean isDefaultSerializer(JsonSerializer<?> serializer) {
return ClassUtil.isJacksonStdImpl(serializer);
}
/**
* Helper method that can be used to see if specified property has annotation
* indicating that a converter is to be used for contained values (contents
* of structured types; array/List/Map values)
*
* @param existingSerializer (optional) configured content
* serializer if one already exists.
*
* @since 2.2
*/
protected JsonSerializer<?> findConvertingContentSerializer(SerializerProvider provider,
BeanProperty prop, JsonSerializer<?> existingSerializer)
throws JsonMappingException
{
final AnnotationIntrospector intr = provider.getAnnotationIntrospector();
if (intr != null && prop != null) {
Object convDef = intr.findSerializationContentConverter(prop.getMember());
if (convDef != null) {
Converter<Object,Object> conv = provider.converterInstance(prop.getMember(), convDef);
JavaType delegateType = conv.getOutputType(provider.getTypeFactory());
if (existingSerializer == null) {
existingSerializer = provider.findValueSerializer(delegateType, prop);
}
return new StdDelegatingSerializer(conv, delegateType, existingSerializer);
}
}
return existingSerializer;
}
/**
* Helper method used to locate filter that is needed, based on filter id
* this serializer was constructed with.
*
* @since 2.3
*/
protected PropertyFilter findPropertyFilter(SerializerProvider provider,
Object filterId, Object valueToFilter)
throws JsonMappingException
{
FilterProvider filters = provider.getFilterProvider();
// Not ok to miss the provider, if a filter is declared to be needed.
if (filters == null) {
throw new JsonMappingException("Can not resolve PropertyFilter with id '"+filterId+"'; no FilterProvider configured");
}
PropertyFilter filter = filters.findPropertyFilter(filterId, valueToFilter);
// But whether unknown ids are ok just depends on filter provider; if we get null that's fine
return filter;
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> if (_delegateDeserializer != null) {
return (Collection<Object>) _valueInstantiator.createUsingDelegate(ctxt,
_delegateDeserializer.deserialize(jp, ctxt));
}
/* [JACKSON-620]: empty String may be ok; bit tricky to check, however, since
* there is also possibility of "auto-wrapping" of single-element arrays.
* Hence we only accept empty String here.
*/
if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
String str = jp.getText();
if (str.length() == 0) {
return (Collection<Object>) _valueInstantiator.createFromString(ctxt, str);
}
}
return deserialize(jp, ctxt, (Collection<Object>) _valueInstantiator.createUsingDefault(ctxt));
}
@Override
public Collection<Object> deserialize(JsonParser jp, DeserializationContext ctxt,
Collection<Object> result)
throws IOException, JsonProcessingException
{
// Ok: must point to START_ARRAY (or equivalent)
if (!jp.isExpectedStartArrayToken()) {
return handleNonArray(jp, ctxt, result);
}
JsonDeserializer<Object> valueDes = _valueDeserializer;
final TypeDeserializer typeDeser = _valueTypeDeserializer;
CollectionReferringAccumulator referringAccumulator =
(valueDes.getObjectIdReader() == null) ? null :
new CollectionReferringAccumulator(_collectionType.getContentType().getRawClass(), result);
JsonToken t;
while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
try {
Object value;
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue();
} else if (typeDeser == null) {
value = valueDes.deserialize(jp, ctxt);
} else {
value = valueDes.deserializeWithType(jp, ctxt, typeDeser);
}
if (referringAccumulator != null) {
referringAccumulator.add(value);
} else {
result.add(value);
}
} catch (UnresolvedForwardReference reference) {
if (referringAccumulator == null) {
throw JsonMappingException
.from(jp, "Unresolved forward reference but no identity info", reference);
}
Referring ref = referringAccumulator.handleUnresolvedReference(reference);
reference.getRoid().appendReferring(ref);
} catch (Exception e) {
throw JsonMappingException.wrapWithPath(e, result, result.size());
}
}
return result;
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
// In future could check current token... for now this should be enough:
return typeDeserializer.deserializeTypedFromArray(jp, ctxt);
}
/**
* Helper method called when current token is no START_ARRAY. Will either
* throw an exception, or try to handle value as if member of implicit
* array, depending on configuration.
*/
protected final Collection<Object> handleNonArray(JsonParser jp, DeserializationContext ctxt,
Collection<Object> result)
throws IOException, JsonProcessingException
{
// [JACKSON-526]: implicit arrays from single values?
if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>SINGLE_VALUE_AS_ARRAY)) {
throw ctxt.mappingException(_collectionType.getRawClass());
}
JsonDeserializer<Object> valueDes = _valueDeserializer;
final TypeDeserializer typeDeser = _valueTypeDeserializer;
JsonToken t = jp.getCurrentToken();
Object value;
try {
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue();
} else if (typeDeser == null) {
value = valueDes.deserialize(jp, ctxt);
} else {
value = valueDes.deserializeWithType(jp, ctxt, typeDeser);
}
} catch (Exception e) {
// note: pass Object.class, not Object[].class, as we need element type for error info
throw JsonMappingException.wrapWithPath(e, Object.class, result.size());
}
result.add(value);
return result;
}
public final static class CollectionReferringAccumulator {
private final Class<?> _elementType;
private final Collection<Object> _result;
/**
* A list of {@link CollectionReferring} to maintain ordering.
*/
private List<CollectionReferring> _accumulator = new ArrayList<CollectionReferring>();
public CollectionReferringAccumulator(Class<?> elementType, Collection<Object> result) {
_elementType = elementType;
_result = result;
}
public void add(Object value)
{
if (_accumulator.isEmpty()) {
_result.add(value);
} else {
CollectionReferring ref = _accumulator.get(_accumulator.size() - 1);
ref.next.add(value);
}
}
public Referring handleUnresolvedReference(UnresolvedForwardReference reference)
{
CollectionReferring id = new CollectionReferring(this, reference, _elementType);
_accumulator.add(id);
return id;
}
public void resolveForwardReference(Object id, Object value) throws IOException
{
Iterator<CollectionReferring> iterator = _accumulator.iterator();
// Resolve ordering after resolution of an id. This mean either:
// 1- adding to the result collection in case of the first unresolved id.
// 2- merge the content of the resolved id with its previous unresolved id.
Collection<Object> previous = _result;
while (iterator.hasNext()) {
CollectionReferring ref = iterator.next();
if (ref.hasId(id)) {
iterator.remove();
previous.add(value);
previous.addAll(ref.next);
return;
}
previous = ref.next;
}
throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id
+ "] that wasn't previously seen as unresolved.");
}
}
/**
* Helper class to maintain processing order of value. The resolved
* object associated with {@link #_id} comes before the values in
* {@link #next}.
*/
private final static class CollectionReferring extends Referring {
private final CollectionReferringAccumulator _parent;
public final List<Object> next = new ArrayList<Object>();
private CollectionReferring(CollectionReferringAccumulator parent,
UnresolvedForwardReference reference, Class<?> contentType)
{
super(reference, contentType);
_parent = parent;
}
@Override
public void handleResolvedForwardReference(Object id, Object value) throws IOException {
_
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>parent.resolveForwardReference(id, value);
}
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* Value node that contains a wrapped POJO, to be serialized as
* a JSON constructed through data mapping (usually done by
* calling {@link com.fasterxml.jackson.databind.ObjectMapper}).
*/
public class POJONode
extends ValueNode
{
protected final Object _value;
public POJONode(Object v) { _value = v; }
/*
/**********************************************************
/* Base class overrides
/**********************************************************
*/
@Override
public JsonNodeType getNodeType()
{
return JsonNodeType.POJO;
}
@Override public JsonToken asToken() { return JsonToken.VALUE_EMBEDDED_OBJECT; }
/**
* As it is possible that some implementations embed byte[] as POJONode
* (despite optimal being {@link BinaryNode}), let's add support for exposing
* binary data here too.
*/
@Override
public byte[] binaryValue() throws IOException
{
if (_value instanceof byte[]) {
return (byte[]) _value;
}
return super.binaryValue();
}
/*
/**********************************************************
/* General type coercions
/**********************************************************
*/
@Override
public String asText() { return (_value == null) ? "null" : _value.toString(); }
@Override public String asText(String defaultValue) {
return (_value == null) ? defaultValue : _value.toString();
}
@Override
public boolean asBoolean(boolean defaultValue)
{
if (_value != null && _value instanceof Boolean) {
return ((Boolean) _value).booleanValue();
}
return defaultValue;
}
@Override
public int asInt(int defaultValue)
{
if (_value instanceof Number) {
return ((Number) _value).intValue();
}
return defaultValue;
}
@Override
public long asLong(long defaultValue)
{
if (_value instanceof Number) {
return ((Number) _value).longValue();
}
return defaultValue;
}
@Override
public double asDouble(double defaultValue)
{
if (_value instanceof Number) {
return ((Number) _value).doubleValue();
}
return defaultValue;
}
/*
/**********************************************************
/* Public API, serialization
/**********************************************************
*/
@Override
public final void serialize(JsonGenerator jg, SerializerProvider provider)
throws IOException, JsonProcessingException
{
if (_value == null) {
provider.defaultSerializeNull(jg);
} else {
jg.writeObject(_value);
}
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
/**
* Method that can be used to access the POJO this node wraps.
*/
public Object getPojo() { return _value; }
/*
/**********************************************************
/* Overridden standard methods
/**********************************************************
*/
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o instanceof POJONode) {
return _pojoEquals((POJONode) o);
}
return false;
}
/**
* @since 2.3
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> /* ContainerDeserializerBase API
/**********************************************************
*/
@Override
public JavaType getContentType() {
return _arrayType.getContentType();
}
@Override
public JsonDeserializer<Object> getContentDeserializer() {
return _elementDeserializer;
}
/*
/**********************************************************
/* JsonDeserializer API
/**********************************************************
*/
@Override
public Object[] deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// Ok: must point to START_ARRAY (or equivalent)
if (!jp.isExpectedStartArrayToken()) {
return handleNonArray(jp, ctxt);
}
final ObjectBuffer buffer = ctxt.leaseObjectBuffer();
Object[] chunk = buffer.resetAndStart();
int ix = 0;
JsonToken t;
final TypeDeserializer typeDeser = _elementTypeDeserializer;
try {
while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
// Note: must handle null explicitly here; value deserializers won't
Object value;
if (t == JsonToken.VALUE_NULL) {
value = _elementDeserializer.getNullValue();
} else if (typeDeser == null) {
value = _elementDeserializer.deserialize(jp, ctxt);
} else {
value = _elementDeserializer.deserializeWithType(jp, ctxt, typeDeser);
}
if (ix >= chunk.length) {
chunk = buffer.appendCompletedChunk(chunk);
ix = 0;
}
chunk[ix++] = value;
}
} catch (Exception e) {
throw JsonMappingException.wrapWithPath(e, chunk, ix);
}
Object[] result;
if (_untyped) {
result = buffer.completeAndClearBuffer(chunk, ix);
} else {
result = buffer.completeAndClearBuffer(chunk, ix, _elementClass);
}
ctxt.returnObjectBuffer(buffer);
return result;
}
@Override
public Object[] deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
/* Should there be separate handling for base64 stuff?
* for now this should be enough:
*/
return (Object[]) typeDeserializer.deserializeTypedFromArray(jp, ctxt);
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
protected Byte[] deserializeFromBase64(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// First same as what PrimitiveArrayDeserializers.ByteDeser does:
byte[] b = jp.getBinaryValue(ctxt.getBase64Variant());
// But then need to convert to wrappers
Byte[] result = new Byte[b.length];
for (int i = 0, len = b.length; i < len; ++i) {
result[i] = Byte.valueOf(b[i]);
}
return result;
}
private final Object[] handleNonArray(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// [JACKSON-620] Empty String can become null...
if ((jp.getCurrentToken() == JsonToken.VALUE_STRING)
&& ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) {
String str = jp.getText();
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
if (str.length() == 0) {
return null;
}
}
// Can we do implicit coercion to a single-element array still?
if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)) {
/* 04-Oct-2009, tatu: One exception; byte arrays are generally
* serialized as base64, so that should be handled
*/
if (jp.getCurrentToken() == JsonToken.VALUE_STRING
&& _elementClass == Byte.class) {
return deserializeFromBase64(jp, ctxt);
}
throw ctxt.mappingException(_arrayType.getRawClass());
}
JsonToken t = jp.getCurrentToken();
Object value;
if (t == JsonToken.VALUE_NULL) {
value = _elementDeserializer.getNullValue();
} else if (_elementTypeDeserializer == null) {
value = _elementDeserializer.deserialize(jp, ctxt);
} else {
value = _elementDeserializer.deserializeWithType(jp, ctxt, _elementTypeDeserializer);
}
// Ok: bit tricky, since we may want T[], not just Object[]
Object[] result;
if (_untyped) {
result = new Object[1];
} else {
result = (Object[]) Array.newInstance(_elementClass, 1);
}
result[0] = value;
return result;
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>Ignore);
}
/**
* Implementation has to check whether as-array serialization
* is possible reliably; if (and only if) so, will construct
* a {@link BeanAsArraySerializer}, otherwise will return this
* serializer as is.
*/
@Override
protected BeanSerializerBase asArraySerializer()
{
/* Can not:
*
* - have Object Id (may be allowed in future)
* - have any getter
*
*/
if ((_objectIdWriter == null)
&& (_anyGetterWriter == null)
&& (_propertyFilterId == null)
) {
return new BeanAsArraySerializer(this);
}
// already is one, so:
return this;
}
/*
/**********************************************************
/* JsonSerializer implementation that differs between impls
/**********************************************************
*/
/**
* Main serialization method that will delegate actual output to
* configured
* {@link BeanPropertyWriter} instances.
*/
@Override
public final void serialize(Object bean, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
if (_objectIdWriter != null) {
_serializeWithObjectId(bean, jgen, provider, true);
return;
}
jgen.writeStartObject();
if (_propertyFilterId != null) {
serializeFieldsFiltered(bean, jgen, provider);
} else {
serializeFields(bean, jgen, provider);
}
jgen.writeEndObject();
}
/*
/**********************************************************
/* Standard methods
/**********************************************************
*/
@Override public String toString() {
return "BeanSerializer for "+handledType().getName();
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
* like Afterburner change definition.
*/
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
// common case first:
if (t == JsonToken.START_OBJECT) {
if (_vanillaProcessing) {
return vanillaDeserialize(jp, ctxt, jp.nextToken());
}
jp.nextToken();
if (_objectIdReader != null) {
return deserializeWithObjectId(jp, ctxt);
}
return deserializeFromObject(jp, ctxt);
}
return _deserializeOther(jp, ctxt, t);
}
protected final Object _deserializeOther(JsonParser jp, DeserializationContext ctxt,
JsonToken t) throws IOException
{
// and then others, generally requiring use of @JsonCreator
switch (t) {
case VALUE_STRING:
return deserializeFromString(jp, ctxt);
case VALUE_NUMBER_INT:
return deserializeFromNumber(jp, ctxt);
case VALUE_NUMBER_FLOAT:
return deserializeFromDouble(jp, ctxt);
case VALUE_EMBEDDED_OBJECT:
return deserializeFromEmbedded(jp, ctxt);
case VALUE_TRUE:
case VALUE_FALSE:
return deserializeFromBoolean(jp, ctxt);
case START_ARRAY:
// these only work if there's a (delegating) creator...
return deserializeFromArray(jp, ctxt);
case FIELD_NAME:
case END_OBJECT: // added to resolve [JACKSON-319], possible related issues
if (_vanillaProcessing) {
return vanillaDeserialize(jp, ctxt, t);
}
if (_objectIdReader != null) {
return deserializeWithObjectId(jp, ctxt);
}
return deserializeFromObject(jp, ctxt);
default:
throw ctxt.mappingException(handledType());
}
}
protected Object _missingToken(JsonParser jp, DeserializationContext ctxt)
throws JsonProcessingException
{
throw ctxt.endOfInputException(handledType());
}
/**
* Secondary deserialization method, called in cases where POJO
* instance is created as part of deserialization, potentially
* after collecting some or all of the properties to set.
*/
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt, Object bean)
throws IOException, JsonProcessingException
{
if (_injectables != null) {
injectValues(ctxt, bean);
}
if (_unwrappedPropertyHandler != null) {
return deserializeWithUnwrapped(jp, ctxt, bean);
}
if (_externalTypeIdHandler != null) {
return deserializeWithExternalTypeId(jp, ctxt, bean);
}
JsonToken t = jp.getCurrentToken();
// 23-Mar-2010, tatu: In some cases, we start with full JSON object too...
if (t == JsonToken.START_OBJECT) {
t = jp.nextToken();
}
if (_needViewProcesing) {
Class<?> view = ctxt.getActiveView();
if (view != null) {
return deserializeWithView(jp, ctxt, bean, view);
}
}
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
// Skip field name:
jp.nextToken();
SettableBeanProperty prop
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> = _beanProperties.find(propName);
if (prop != null) { // normal case
try {
prop.deserializeAndSet(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
handleUnknownVanilla(jp, ctxt, bean, propName);
}
return bean;
}
/*
/**********************************************************
/* Concrete deserialization methods
/**********************************************************
*/
/**
* Streamlined version that is only used when no "special"
* features are enabled.
*/
private final Object vanillaDeserialize(JsonParser jp,
DeserializationContext ctxt, JsonToken t)
throws IOException, JsonProcessingException
{
final Object bean = _valueInstantiator.createUsingDefault(ctxt);
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
// Skip field name:
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
try {
prop.deserializeAndSet(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
} else {
handleUnknownVanilla(jp, ctxt, bean, propName);
}
}
return bean;
}
/**
* General version used when handling needs more advanced
* features.
*/
@Override
public Object deserializeFromObject(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (_nonStandardCreation) {
if (_unwrappedPropertyHandler != null) {
return deserializeWithUnwrapped(jp, ctxt);
}
if (_externalTypeIdHandler != null) {
return deserializeWithExternalTypeId(jp, ctxt);
}
Object bean = deserializeFromObjectUsingNonDefault(jp, ctxt);
if (_injectables != null) {
injectValues(ctxt, bean);
}
/* 27-May-2014, tatu: I don't think view processing would work
* at this point, so commenting it out; but leaving in place
* just in case I forgot something fundamental...
*/
/*
if (_needViewProcesing) {
Class<?> view = ctxt.getActiveView();
if (view != null) {
return deserializeWithView(jp, ctxt, bean, view);
}
}
*/
return bean;
}
final Object bean = _valueInstantiator.createUsingDefault(ctxt);
if (jp.canReadObjectId()) {
Object id = jp.getObjectId();
if (id != null) {
_handleTypedObjectId(jp, ctxt, bean, id);
}
}
if (_injectables != null) {
injectValues(ctxt, bean);
}
if (_needViewProcesing) {
Class<?> view = ctxt.getActiveView();
if (view != null) {
return deserializeWithView(jp, ctxt, bean, view);
}
}
JsonToken t = jp.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
// Skip field name:
jp.nextToken();
SettableBeanProperty
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> prop = _beanProperties.find(propName);
if (prop != null) { // normal case
try {
prop.deserializeAndSet(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
handleUnknownVanilla(jp, ctxt, bean, propName);
}
return bean;
}
/**
* Method called to deserialize bean using "property-based creator":
* this means that a non-default constructor or factory method is
* called, and then possibly other setters. The trick is that
* values for creator method need to be buffered, first; and
* due to non-guaranteed ordering possibly some other properties
* as well.
*/
@Override
@SuppressWarnings("resource")
protected Object _deserializeUsingPropertyBased(final JsonParser jp, final DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
final PropertyBasedCreator creator = _propertyBasedCreator;
PropertyValueBuffer buffer = creator.startBuilding(jp, ctxt, _objectIdReader);
// 04-Jan-2010, tatu: May need to collect unknown properties for polymorphic cases
TokenBuffer unknown = null;
JsonToken t = jp.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
jp.nextToken(); // to point to value
// creator property?
SettableBeanProperty creatorProp = creator.findCreatorProperty(propName);
if (creatorProp != null) {
// Last creator property to set?
Object value = creatorProp.deserialize(jp, ctxt);
if (buffer.assignParameter(creatorProp.getCreatorIndex(), value)) {
jp.nextToken(); // to move to following FIELD_NAME/END_OBJECT
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
bean = null; // never gets here
}
// polymorphic?
if (bean.getClass() != _beanType.getRawClass()) {
return handlePolymorphic(jp, ctxt, bean, unknown);
}
if (unknown != null) { // nope, just extra unknown stuff...
bean = handleUnknownProperties(ctxt, bean, unknown);
}
// or just clean?
return deserialize(jp, ctxt, bean);
}
continue;
}
// Object Id property?
if (buffer.readIdProperty(propName)) {
continue;
}
// regular property? needs buffering
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) {
buffer.bufferProperty(prop, prop.deserialize(jp, ctxt));
continue;
}
// As per [JACKSON-313], things marked as ignorable should not be
// passed to any setter
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, handledType(), propName);
continue;
}
// "any property"?
if (_anySetter != null) {
buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(jp, ctxt
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>));
continue;
}
// Ok then, let's collect the whole field; name and value
if (unknown == null) {
unknown = new TokenBuffer(jp);
}
unknown.writeFieldName(propName);
unknown.copyCurrentStructure(jp);
}
// We hit END_OBJECT, so:
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
bean = null; // never gets here
}
if (unknown != null) {
// polymorphic?
if (bean.getClass() != _beanType.getRawClass()) {
return handlePolymorphic(null, ctxt, bean, unknown);
}
// no, just some extra unknown properties
return handleUnknownProperties(ctxt, bean, unknown);
}
return bean;
}
/*
/**********************************************************
/* Deserializing when we have to consider an active View
/**********************************************************
*/
protected final Object deserializeWithView(JsonParser jp, DeserializationContext ctxt,
Object bean, Class<?> activeView)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
// Skip field name:
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) {
if (!prop.visibleInView(activeView)) {
jp.skipChildren();
continue;
}
try {
prop.deserializeAndSet(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
handleUnknownVanilla(jp, ctxt, bean, propName);
}
return bean;
}
/*
/**********************************************************
/* Handling for cases where we have "unwrapped" values
/**********************************************************
*/
/**
* Method called when there are declared "unwrapped" properties
* which need special handling
*/
@SuppressWarnings("resource")
protected Object deserializeWithUnwrapped(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (_delegateDeserializer != null) {
return _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt));
}
if (_propertyBasedCreator != null) {
return deserializeUsingPropertyBasedWithUnwrapped(jp, ctxt);
}
TokenBuffer tokens = new TokenBuffer(jp);
tokens.writeStartObject();
final Object bean = _valueInstantiator.createUsingDefault(ctxt);
if (_injectables != null) {
injectValues(ctxt, bean);
}
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) {
String propName = jp.getCurrentName();
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
if (activeView != null && !prop.visibleInView(activeView)) {
jp.skipChildren();
continue;
}
try {
prop.deserializeAndSet(jp, ctxt, bean
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
// ignorable things should be ignored
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, bean, propName);
continue;
}
// but... others should be passed to unwrapped property deserializers
tokens.writeFieldName(propName);
tokens.copyCurrentStructure(jp);
// how about any setter? We'll get copies but...
if (_anySetter != null) {
try {
_anySetter.deserializeAndSet(jp, ctxt, bean, propName);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
}
tokens.writeEndObject();
_unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens);
return bean;
}
@SuppressWarnings("resource")
protected Object deserializeWithUnwrapped(JsonParser jp, DeserializationContext ctxt, Object bean)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.START_OBJECT) {
t = jp.nextToken();
}
TokenBuffer tokens = new TokenBuffer(jp);
tokens.writeStartObject();
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
SettableBeanProperty prop = _beanProperties.find(propName);
jp.nextToken();
if (prop != null) { // normal case
if (activeView != null && !prop.visibleInView(activeView)) {
jp.skipChildren();
continue;
}
try {
prop.deserializeAndSet(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, bean, propName);
continue;
}
// but... others should be passed to unwrapped property deserializers
tokens.writeFieldName(propName);
tokens.copyCurrentStructure(jp);
// how about any setter? We'll get copies but...
if (_anySetter != null) {
_anySetter.deserializeAndSet(jp, ctxt, bean, propName);
}
}
tokens.writeEndObject();
_unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens);
return bean;
}
@SuppressWarnings("resource")
protected Object deserializeUsingPropertyBasedWithUnwrapped(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
final PropertyBasedCreator creator = _propertyBasedCreator;
PropertyValueBuffer buffer = creator.startBuilding(jp, ctxt, _objectIdReader);
TokenBuffer tokens = new TokenBuffer(jp);
tokens.writeStartObject();
JsonToken t = jp.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
jp.nextToken(); // to point to value
//
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> creator property?
SettableBeanProperty creatorProp = creator.findCreatorProperty(propName);
if (creatorProp != null) {
// Last creator property to set?
Object value = creatorProp.deserialize(jp, ctxt);
if (buffer.assignParameter(creatorProp.getCreatorIndex(), value)) {
t = jp.nextToken(); // to move to following FIELD_NAME/END_OBJECT
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
continue; // never gets here
}
// if so, need to copy all remaining tokens into buffer
while (t == JsonToken.FIELD_NAME) {
jp.nextToken(); // to skip name
tokens.copyCurrentStructure(jp);
t = jp.nextToken();
}
tokens.writeEndObject();
if (bean.getClass() != _beanType.getRawClass()) {
// !!! 08-Jul-2011, tatu: Could probably support; but for now
// it's too complicated, so bail out
tokens.close();
throw ctxt.mappingException("Can not create polymorphic instances with unwrapped values");
}
return _unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens);
}
continue;
}
// Object Id property?
if (buffer.readIdProperty(propName)) {
continue;
}
// regular property? needs buffering
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) {
buffer.bufferProperty(prop, prop.deserialize(jp, ctxt));
continue;
}
/* As per [JACKSON-313], things marked as ignorable should not be
* passed to any setter
*/
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, handledType(), propName);
continue;
}
tokens.writeFieldName(propName);
tokens.copyCurrentStructure(jp);
// "any property"?
if (_anySetter != null) {
buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(jp, ctxt));
}
}
// We hit END_OBJECT, so:
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
return null; // never gets here
}
return _unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens);
}
/*
/**********************************************************
/* Handling for cases where we have property/-ies with
/* external type id
/**********************************************************
*/
protected Object deserializeWithExternalTypeId(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (_propertyBasedCreator != null) {
return deserializeUsingPropertyBasedWithExternalTypeId(jp, ctxt);
}
return deserializeWithExternalTypeId(jp, ctxt, _valueInstantiator.createUsingDefault(ctxt));
}
protected Object deserializeWithExternalTypeId(JsonParser jp, DeserializationContext ctxt,
Object bean)
throws IOException, JsonProcessingException
{
final Class<?> activeView = _needViewProcesing ?
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> ctxt.getActiveView() : null;
final ExternalTypeHandler ext = _externalTypeIdHandler.start();
JsonToken t = jp.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
// [JACKSON-831]: may have property AND be used as external type id:
if (jp.getCurrentToken().isScalarValue()) {
ext.handleTypePropertyValue(jp, ctxt, propName, bean);
}
if (activeView != null && !prop.visibleInView(activeView)) {
jp.skipChildren();
continue;
}
try {
prop.deserializeAndSet(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
// ignorable things should be ignored
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, bean, propName);
continue;
}
// but others are likely to be part of external type id thingy...
if (ext.handlePropertyValue(jp, ctxt, propName, bean)) {
continue;
}
// if not, the usual fallback handling:
if (_anySetter != null) {
try {
_anySetter.deserializeAndSet(jp, ctxt, bean, propName);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
// Unknown: let's call handler method
handleUnknownProperty(jp, ctxt, bean, propName);
}
// and when we get this far, let's try finalizing the deal:
return ext.complete(jp, ctxt, bean);
}
@SuppressWarnings("resource")
protected Object deserializeUsingPropertyBasedWithExternalTypeId(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
final ExternalTypeHandler ext = _externalTypeIdHandler.start();
final PropertyBasedCreator creator = _propertyBasedCreator;
PropertyValueBuffer buffer = creator.startBuilding(jp, ctxt, _objectIdReader);
TokenBuffer tokens = new TokenBuffer(jp);
tokens.writeStartObject();
JsonToken t = jp.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
jp.nextToken(); // to point to value
// creator property?
SettableBeanProperty creatorProp = creator.findCreatorProperty(propName);
if (creatorProp != null) {
// first: let's check to see if this might be part of value with external type id:
if (ext.handlePropertyValue(jp, ctxt, propName, buffer)) {
;
} else {
// Last creator property to set?
Object value = creatorProp.deserialize(jp, ctxt);
if (buffer.assignParameter(creatorProp.getCreatorIndex(), value)) {
t = jp.nextToken(); // to move to following FIELD_NAME/END_OBJECT
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e)
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> {
wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
continue; // never gets here
}
// if so, need to copy all remaining tokens into buffer
while (t == JsonToken.FIELD_NAME) {
jp.nextToken(); // to skip name
tokens.copyCurrentStructure(jp);
t = jp.nextToken();
}
if (bean.getClass() != _beanType.getRawClass()) {
// !!! 08-Jul-2011, tatu: Could probably support; but for now
// it's too complicated, so bail out
throw ctxt.mappingException("Can not create polymorphic instances with unwrapped values");
}
return ext.complete(jp, ctxt, bean);
}
}
continue;
}
// Object Id property?
if (buffer.readIdProperty(propName)) {
continue;
}
// regular property? needs buffering
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) {
buffer.bufferProperty(prop, prop.deserialize(jp, ctxt));
continue;
}
// external type id (or property that depends on it)?
if (ext.handlePropertyValue(jp, ctxt, propName, null)) {
continue;
}
/* As per [JACKSON-313], things marked as ignorable should not be
* passed to any setter
*/
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, handledType(), propName);
continue;
}
// "any property"?
if (_anySetter != null) {
buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(jp, ctxt));
}
}
// We hit END_OBJECT; resolve the pieces:
try {
return ext.complete(jp, ctxt, buffer, creator);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
return null; // never gets here
}
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
/**
* Intermediate base class for limited number of scalar types
* that should never include type information. These are "native"
* types that are default mappings for corresponding JSON scalar
* types: {@link java.lang.String}, {@link java.lang.Integer},
* {@link java.lang.Double} and {@link java.lang.Boolean}.
*/
public abstract class NonTypedScalarSerializerBase<T>
extends StdScalarSerializer<T>
{
protected NonTypedScalarSerializerBase(Class<T> t) {
super(t);
}
@Override
public final void serializeWithType(T value, JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer)
throws IOException, JsonGenerationException
{
// no type info, just regular serialization
serialize(value, jgen, provider);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId;
/**
* Exception thrown during deserialization when there are object id that can't
* be resolved.
*
* @author pgelinas
*/
public final class UnresolvedForwardReference extends JsonMappingException {
private static final long serialVersionUID = 1L;
private ReadableObjectId _roid;
private List<UnresolvedId> _unresolvedIds;
public UnresolvedForwardReference(String msg, JsonLocation loc, ReadableObjectId roid)
{
super(msg, loc);
_roid = roid;
}
public UnresolvedForwardReference(String msg)
{
super(msg);
_unresolvedIds = new ArrayList<UnresolvedId>();
}
// ******************************
// ****** Accessor methods ******
// ******************************
public ReadableObjectId getRoid() {
return _roid;
}
public Object getUnresolvedId() {
return _roid.getKey().key;
}
public void addUnresolvedId(Object id, Class<?> type, JsonLocation where) {
_unresolvedIds.add(new UnresolvedId(id, type, where));
}
public List<UnresolvedId> getUnresolvedIds(){
return _unresolvedIds;
}
@Override
public String getMessage()
{
String msg = super.getMessage();
if (_unresolvedIds == null) {
return msg;
}
StringBuilder sb = new StringBuilder(msg);
Iterator<UnresolvedId> iterator = _unresolvedIds.iterator();
while (iterator.hasNext()) {
UnresolvedId unresolvedId = iterator.next();
sb.append(unresolvedId.toString());
if (iterator.hasNext()) {
sb.append(", ");
}
}
sb.append('.');
return sb.toString();
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> content.
*<p>
* Note that the method does NOT change state of this reader, but
* rather construct and returns a newly configured instance.
*/
public ObjectReader with(FormatSchema schema)
{
if (_schema == schema) {
return this;
}
_verifySchemaType(schema);
return new ObjectReader(this, _config, _valueType, _rootDeserializer, _valueToUpdate,
schema, _injectableValues, _dataFormatReaders);
}
/**
* Method for constructing a new reader instance that is configured
* to data bind into specified type.
*<p>
* Note that the method does NOT change state of this reader, but
* rather construct and returns a newly configured instance.
*/
public ObjectReader withType(JavaType valueType)
{
if (valueType != null && valueType.equals(_valueType)) {
return this;
}
JsonDeserializer<Object> rootDeser = _prefetchRootDeserializer(_config, valueType);
// type is stored here, no need to make a copy of config
DataFormatReaders det = _dataFormatReaders;
if (det != null) {
det = det.withType(valueType);
}
return new ObjectReader(this, _config, valueType, rootDeser,
_valueToUpdate, _schema, _injectableValues, det);
}
/**
* Method for constructing a new reader instance that is configured
* to data bind into specified type.
*<p>
* Note that the method does NOT change state of this reader, but
* rather construct and returns a newly configured instance.
*/
public ObjectReader withType(Class<?> valueType) {
return withType(_config.constructType(valueType));
}
/**
* Method for constructing a new reader instance that is configured
* to data bind into specified type.
*<p>
* Note that the method does NOT change state of this reader, but
* rather construct and returns a newly configured instance.
*/
public ObjectReader withType(java.lang.reflect.Type valueType) {
return withType(_config.getTypeFactory().constructType(valueType));
}
/**
* Method for constructing a new reader instance that is configured
* to data bind into specified type.
*<p>
* Note that the method does NOT change state of this reader, but
* rather construct and returns a newly configured instance.
*/
public ObjectReader withType(TypeReference<?> valueTypeRef) {
return withType(_config.getTypeFactory().constructType(valueTypeRef.getType()));
}
/**
* Method for constructing a new instance with configuration that
* updates passed Object (as root value), instead of constructing
* a new value.
*<p>
* Note that the method does NOT change state of this reader, but
* rather construct and returns a newly configured instance.
*/
public ObjectReader withValueToUpdate(Object value)
{
if (value == _valueToUpdate) return this;
if (value == null) {
throw new IllegalArgumentException("cat not update null value");
}
JavaType t;
/* no real benefit from pre-fetching, as updating readers are much
* less likely to be reused, and value type may also be forced
* with a later chained call...
*/
if (_valueType == null) {
t = _config.
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>constructType(value.getClass());
} else {
t = _valueType;
}
return new ObjectReader(this, _config, t, _rootDeserializer, value,
_schema, _injectableValues, _dataFormatReaders);
}
/**
* Method for constructing a new instance with configuration that
* uses specified View for filtering.
*<p>
* Note that the method does NOT change state of this reader, but
* rather construct and returns a newly configured instance.
*/
public ObjectReader withView(Class<?> activeView) {
return _with(_config.withView(activeView));
}
public ObjectReader with(Locale l) {
return _with(_config.with(l));
}
public ObjectReader with(TimeZone tz) {
return _with(_config.with(tz));
}
public ObjectReader withHandler(DeserializationProblemHandler h) {
return _with(_config.withHandler(h));
}
public ObjectReader with(Base64Variant defaultBase64) {
return _with(_config.with(defaultBase64));
}
/**
* Fluent factory method for constructing a reader that will try to
* auto-detect underlying data format, using specified list of
* {@link JsonFactory} instances, and default {@link DataFormatReaders} settings
* (for customized {@link DataFormatReaders}, you can construct instance yourself).
* to construct appropriate {@link JsonParser} for actual parsing.
*<p>
* Note: since format detection only works with byte sources, it is possible to
* get a failure from some 'readValue()' methods. Also, if input can not be reliably
* (enough) detected as one of specified types, an exception will be thrown.
*<p>
* Note: not all {@link JsonFactory} types can be passed: specifically, ones that
* require "custom codec" (like XML factory) will not work. Instead, use
* method that takes {@link ObjectReader} instances instead of factories.
*
* @param readers Data formats accepted, in decreasing order of priority (that is,
* matches checked in listed order, first match wins)
*
* @return Newly configured writer instance
*
* @since 2.1
*/
public ObjectReader withFormatDetection(ObjectReader... readers)
{
return withFormatDetection(new DataFormatReaders(readers));
}
/**
* Fluent factory method for constructing a reader that will try to
* auto-detect underlying data format, using specified
* {@link DataFormatReaders}.
*<p>
* NOTE: since format detection only works with byte sources, it is possible to
* get a failure from some 'readValue()' methods. Also, if input can not be reliably
* (enough) detected as one of specified types, an exception will be thrown.
*
* @param readers DataFormatReaders to use for detecting underlying format.
*
* @return Newly configured writer instance
*
* @since 2.1
*/
public ObjectReader withFormatDetection(DataFormatReaders readers)
{
return new ObjectReader(this, _config, _valueType, _rootDeserializer, _valueToUpdate,
_schema, _injectableValues, readers);
}
/**
* @since 2.3
*/
public ObjectReader with
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> for reading sequence of Objects from parser stream.
*<p>
* Sequence can be either wrapped or unwrapped root-level sequence:
* wrapped means that the elements are enclosed in JSON Array;
* and unwrapped that elements are directly accessed at main level.
* Assumption is that iff the first token of the document is
* <code>START_ARRAY</code>, we have a wrapped sequence; otherwise
* unwrapped. For wrapped sequences, leading <code>START_ARRAY</code>
* is skipped, so that for both cases, underlying {@link JsonParser}
* will point to what is expected to be the first token of the first
* element.
*<p>
* Note that the wrapped vs unwrapped logic means that it is NOT
* possible to use this method for reading an unwrapped sequence
* of elements written as JSON Arrays: to read such sequences, one
* has to use {@link #readValues(JsonParser)}, making sure parser
* points to the first token of the first element (i.e. the second
* <code>START_ARRAY</code> which is part of the first element).
*/
public <T> MappingIterator<T> readValues(InputStream src)
throws IOException, JsonProcessingException
{
if (_dataFormatReaders != null) {
return _detectBindAndReadValues(_dataFormatReaders.findFormat(src), false);
}
return _bindAndReadValues(_parserFactory.createParser(src), _valueToUpdate);
}
/**
* Overloaded version of {@link #readValue(InputStream)}.
*/
@SuppressWarnings("resource")
public <T> MappingIterator<T> readValues(Reader src)
throws IOException, JsonProcessingException
{
if (_dataFormatReaders != null) {
_reportUndetectableSource(src);
}
JsonParser jp = _parserFactory.createParser(src);
if (_schema != null) {
jp.setSchema(_schema);
}
jp.nextToken();
DeserializationContext ctxt = createDeserializationContext(jp, _config);
return new MappingIterator<T>(_valueType, jp, ctxt,
_findRootDeserializer(ctxt, _valueType), true, _valueToUpdate);
}
/**
* Overloaded version of {@link #readValue(InputStream)}.
*
* @param json String that contains JSON content to parse
*/
@SuppressWarnings("resource")
public <T> MappingIterator<T> readValues(String json)
throws IOException, JsonProcessingException
{
if (_dataFormatReaders != null) {
_reportUndetectableSource(json);
}
JsonParser jp = _parserFactory.createParser(json);
if (_schema != null) {
jp.setSchema(_schema);
}
jp.nextToken();
DeserializationContext ctxt = createDeserializationContext(jp, _config);
return new MappingIterator<T>(_valueType, jp, ctxt,
_findRootDeserializer(ctxt, _valueType), true, _valueToUpdate);
}
/**
* Overloaded version of {@link #readValue(InputStream)}.
*/
public <T> MappingIterator<T> readValues(byte[] src, int offset, int length)
throws IOException, JsonProcessingException
{
if (_dataFormatReaders != null) {
return _detectBindAndReadValues(_dataFormatReaders.findFormat(src, offset,
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> length), false);
}
return _bindAndReadValues(_parserFactory.createParser(src), _valueToUpdate);
}
/**
* Overloaded version of {@link #readValue(InputStream)}.
*/
public final <T> MappingIterator<T> readValues(byte[] src)
throws IOException, JsonProcessingException {
return readValues(src, 0, src.length);
}
/**
* Overloaded version of {@link #readValue(InputStream)}.
*/
public <T> MappingIterator<T> readValues(File src)
throws IOException, JsonProcessingException
{
if (_dataFormatReaders != null) {
return _detectBindAndReadValues(
_dataFormatReaders.findFormat(_inputStream(src)), false);
}
return _bindAndReadValues(_parserFactory.createParser(src), _valueToUpdate);
}
/**
* Overloaded version of {@link #readValue(InputStream)}.
*
* @param src URL to read to access JSON content to parse.
*/
public <T> MappingIterator<T> readValues(URL src)
throws IOException, JsonProcessingException
{
if (_dataFormatReaders != null) {
return _detectBindAndReadValues(
_dataFormatReaders.findFormat(_inputStream(src)), true);
}
return _bindAndReadValues(_parserFactory.createParser(src), _valueToUpdate);
}
/*
/**********************************************************
/* Implementation of rest of ObjectCodec methods
/**********************************************************
*/
@Override
public <T> T treeToValue(TreeNode n, Class<T> valueType)
throws JsonProcessingException
{
try {
return readValue(treeAsTokens(n), valueType);
} catch (JsonProcessingException e) {
throw e;
} catch (IOException e) { // should not occur, no real i/o...
throw new IllegalArgumentException(e.getMessage(), e);
}
}
@Override
public void writeValue(JsonGenerator jgen, Object value) throws IOException, JsonProcessingException
{
throw new UnsupportedOperationException("Not implemented for ObjectReader");
}
/*
/**********************************************************
/* Helper methods, data-binding
/**********************************************************
*/
/**
* Actual implementation of value reading+binding operation.
*/
protected Object _bind(JsonParser jp, Object valueToUpdate)
throws IOException, JsonParseException, JsonMappingException
{
/* First: may need to read the next token, to initialize state (either
* before first read from parser, or after previous token has been cleared)
*/
Object result;
JsonToken t = _initForReading(jp);
if (t == JsonToken.VALUE_NULL) {
if (valueToUpdate == null) {
DeserializationContext ctxt = createDeserializationContext(jp, _config);
result = _findRootDeserializer(ctxt, _valueType).getNullValue();
} else {
result = valueToUpdate;
}
} else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) {
result = valueToUpdate;
} else { // pointing to event other than null
DeserializationContext ctxt = createDeserializationContext(jp, _config);
JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, _valueType);
if (_unwrapRoot) {
result = _unwrapAndDeserialize(jp, ctxt, _valueType, deser);
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
} else {
if (valueToUpdate == null) {
result = deser.deserialize(jp, ctxt);
} else {
deser.deserialize(jp, ctxt, valueToUpdate);
result = valueToUpdate;
}
}
}
// Need to consume the token too
jp.clearCurrentToken();
return result;
}
protected Object _bindAndClose(JsonParser jp, Object valueToUpdate)
throws IOException, JsonParseException, JsonMappingException
{
if (_schema != null) {
jp.setSchema(_schema);
}
try {
Object result;
JsonToken t = _initForReading(jp);
if (t == JsonToken.VALUE_NULL) {
if (valueToUpdate == null) {
DeserializationContext ctxt = createDeserializationContext(jp, _config);
result = _findRootDeserializer(ctxt, _valueType).getNullValue();
} else {
result = valueToUpdate;
}
} else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) {
result = valueToUpdate;
} else {
DeserializationContext ctxt = createDeserializationContext(jp, _config);
JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, _valueType);
if (_unwrapRoot) {
result = _unwrapAndDeserialize(jp, ctxt, _valueType, deser);
} else {
if (valueToUpdate == null) {
result = deser.deserialize(jp, ctxt);
} else {
deser.deserialize(jp, ctxt, valueToUpdate);
result = valueToUpdate;
}
}
}
return result;
} finally {
try {
jp.close();
} catch (IOException ioe) { }
}
}
protected JsonNode _bindAsTree(JsonParser jp)
throws IOException, JsonParseException, JsonMappingException
{
JsonNode result;
JsonToken t = _initForReading(jp);
if (t == JsonToken.VALUE_NULL || t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) {
result = NullNode.instance;
} else {
DeserializationContext ctxt = createDeserializationContext(jp, _config);
JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, JSON_NODE_TYPE);
if (_unwrapRoot) {
result = (JsonNode) _unwrapAndDeserialize(jp, ctxt, JSON_NODE_TYPE, deser);
} else {
result = (JsonNode) deser.deserialize(jp, ctxt);
}
}
// Need to consume the token too
jp.clearCurrentToken();
return result;
}
protected JsonNode _bindAndCloseAsTree(JsonParser jp)
throws IOException, JsonParseException, JsonMappingException
{
if (_schema != null) {
jp.setSchema(_schema);
}
try {
return _bindAsTree(jp);
} finally {
try {
jp.close();
} catch (IOException ioe) { }
}
}
/**
* @since 2.1
*/
protected <T> MappingIterator<T> _bindAndReadValues(JsonParser p,
Object valueToUpdate)
throws IOException, JsonProcessingException
{
if (_schema != null) {
p.setSchema(_schema);
}
p.nextToken();
DeserializationContext ctxt = createDeserializationContext(p, _config);
return
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> new MappingIterator<T>(_valueType, p, ctxt,
_findRootDeserializer(ctxt, _valueType),
true, _valueToUpdate);
}
protected static JsonToken _initForReading(JsonParser jp)
throws IOException, JsonParseException, JsonMappingException
{
/* First: must point to a token; if not pointing to one, advance.
* This occurs before first read from JsonParser, as well as
* after clearing of current token.
*/
JsonToken t = jp.getCurrentToken();
if (t == null) { // and then we must get something...
t = jp.nextToken();
if (t == null) {
/* [JACKSON-546] Throw mapping exception, since it's failure to map,
* not an actual parsing problem
*/
throw JsonMappingException.from(jp, "No content to map due to end-of-input");
}
}
return t;
}
/**
* Method called to locate deserializer for the passed root-level value.
*/
protected JsonDeserializer<Object> _findRootDeserializer(DeserializationContext ctxt,
JavaType valueType)
throws JsonMappingException
{
if (_rootDeserializer != null) {
return _rootDeserializer;
}
// Sanity check: must have actual type...
if (valueType == null) {
throw new JsonMappingException("No value type configured for ObjectReader");
}
// First: have we already seen it?
JsonDeserializer<Object> deser = _rootDeserializers.get(valueType);
if (deser != null) {
return deser;
}
// Nope: need to ask provider to resolve it
deser = ctxt.findRootValueDeserializer(valueType);
if (deser == null) { // can this happen?
throw new JsonMappingException("Can not find a deserializer for type "+valueType);
}
_rootDeserializers.put(valueType, deser);
return deser;
}
/**
* Method called to locate deserializer ahead of time, if permitted
* by configuration. Method also is NOT to throw an exception if
* access fails.
*/
protected JsonDeserializer<Object> _prefetchRootDeserializer(
DeserializationConfig config, JavaType valueType)
{
if (valueType == null || !_config.isEnabled(DeserializationFeature.EAGER_DESERIALIZER_FETCH)) {
return null;
}
// already cached?
JsonDeserializer<Object> deser = _rootDeserializers.get(valueType);
if (deser == null) {
try {
// If not, need to resolve; for which we need a temporary context as well:
DeserializationContext ctxt = createDeserializationContext(null, _config);
deser = ctxt.findRootValueDeserializer(valueType);
if (deser != null) {
_rootDeserializers.put(valueType, deser);
}
return deser;
} catch (JsonProcessingException e) {
// need to swallow?
}
}
return deser;
}
protected Object _unwrapAndDeserialize(JsonParser jp, DeserializationContext ctxt,
JavaType rootType, JsonDeserializer<Object> deser)
throws IOException, JsonParseException, JsonMappingException
{
String expName = _config.getRootName();
if (expName == null) {
PropertyName pname = _rootNames.findRootName(rootType, _config);
expName
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> = pname.getSimpleName();
}
if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
throw JsonMappingException.from(jp, "Current token not START_OBJECT (needed to unwrap root name '"
+expName+"'), but "+jp.getCurrentToken());
}
if (jp.nextToken() != JsonToken.FIELD_NAME) {
throw JsonMappingException.from(jp, "Current token not FIELD_NAME (to contain expected root name '"
+expName+"'), but "+jp.getCurrentToken());
}
String actualName = jp.getCurrentName();
if (!expName.equals(actualName)) {
throw JsonMappingException.from(jp, "Root name '"+actualName+"' does not match expected ('"
+expName+"') for type "+rootType);
}
// ok, then move to value itself....
jp.nextToken();
Object result;
if (_valueToUpdate == null) {
result = deser.deserialize(jp, ctxt);
} else {
deser.deserialize(jp, ctxt, _valueToUpdate);
result = _valueToUpdate;
}
// and last, verify that we now get matching END_OBJECT
if (jp.nextToken() != JsonToken.END_OBJECT) {
throw JsonMappingException.from(jp, "Current token not END_OBJECT (to match wrapper object with root name '"
+expName+"'), but "+jp.getCurrentToken());
}
return result;
}
/*
/**********************************************************
/* Internal methods, format auto-detection (since 2.1)
/**********************************************************
*/
@SuppressWarnings("resource")
protected Object _detectBindAndClose(byte[] src, int offset, int length) throws IOException
{
DataFormatReaders.Match match = _dataFormatReaders.findFormat(src, offset, length);
if (!match.hasMatch()) {
_reportUnkownFormat(_dataFormatReaders, match);
}
JsonParser jp = match.createParserWithMatch();
return match.getReader()._bindAndClose(jp, _valueToUpdate);
}
@SuppressWarnings("resource")
protected Object _detectBindAndClose(DataFormatReaders.Match match, boolean forceClosing)
throws IOException
{
if (!match.hasMatch()) {
_reportUnkownFormat(_dataFormatReaders, match);
}
JsonParser p = match.createParserWithMatch();
// One more thing: we Own the input stream now; and while it's
// not super clean way to do it, we must ensure closure so:
if (forceClosing) {
p.enable(JsonParser.Feature.AUTO_CLOSE_SOURCE);
}
// important: use matching ObjectReader (may not be 'this')
return match.getReader()._bindAndClose(p, _valueToUpdate);
}
@SuppressWarnings("resource")
protected <T> MappingIterator<T> _detectBindAndReadValues(DataFormatReaders.Match match, boolean forceClosing)
throws IOException, JsonProcessingException
{
if (!match.hasMatch()) {
_reportUnkownFormat(_dataFormatReaders, match);
}
JsonParser p = match.createParserWithMatch();
// One more thing: we Own the input stream now; and while it's
// not super clean way to do it, we must ensure closure so
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
public JsonValueSerializer withResolved(BeanProperty property,
JsonSerializer<?> ser, boolean forceTypeInfo)
{
if (_property == property && _valueSerializer == ser
&& forceTypeInfo == _forceTypeInformation) {
return this;
}
return new JsonValueSerializer(this, property, ser, forceTypeInfo);
}
/*
/**********************************************************
/* Post-processing
/**********************************************************
*/
/**
* We can try to find the actual serializer for value, if we can
* statically figure out what the result type must be.
*/
@Override
public JsonSerializer<?> createContextual(SerializerProvider provider,
BeanProperty property)
throws JsonMappingException
{
JsonSerializer<?> ser = _valueSerializer;
if (ser == null) {
/* Can only assign serializer statically if the declared type is final:
* if not, we don't really know the actual type until we get the instance.
*/
// 10-Mar-2010, tatu: Except if static typing is to be used
if (provider.isEnabled(MapperFeature.USE_STATIC_TYPING)
|| Modifier.isFinal(_accessorMethod.getReturnType().getModifiers())) {
JavaType t = provider.constructType(_accessorMethod.getGenericReturnType());
// false -> no need to cache
/* 10-Mar-2010, tatu: Ideally we would actually separate out type
* serializer from value serializer; but, alas, there's no access
* to serializer factory at this point...
*/
// 05-Sep-2013, tatu: I _think_ this can be considered a primary property...
ser = provider.findPrimaryPropertySerializer(t, _property);
/* 09-Dec-2010, tatu: Turns out we must add special handling for
* cases where "native" (aka "natural") type is being serialized,
* using standard serializer
*/
boolean forceTypeInformation = isNaturalTypeWithStdHandling(t.getRawClass(), ser);
return withResolved(property, ser, forceTypeInformation);
}
} else {
// 05-Sep-2013, tatu: I _think_ this can be considered a primary property...
ser = provider.handlePrimaryContextualization(ser, property);
return withResolved(property, ser, _forceTypeInformation);
}
return this;
}
/*
/**********************************************************
/* Actual serialization
/**********************************************************
*/
@Override
public void serialize(Object bean, JsonGenerator jgen, SerializerProvider prov)
throws IOException, JsonGenerationException
{
try {
Object value = _accessorMethod.invoke(bean);
if (value == null) {
prov.defaultSerializeNull(jgen);
return;
}
JsonSerializer<Object> ser = _valueSerializer;
if (ser == null) {
Class<?> c = value.getClass();
/* 10-Mar-2010, tatu: Ideally we would actually separate out type
* serializer from value serializer; but, alas, there's no access
* to serializer factory at this point...
*/
// let's cache it, may be needed soon again
ser = prov.findTypedValueSerializer(c, true, _property);
}
ser.serialize(value, j
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>gen, prov);
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
Throwable t = e;
// Need to unwrap this specific type, to see infinite recursion...
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors shouldn't be wrapped (and often can't, as well)
if (t instanceof Error) {
throw (Error) t;
}
// let's try to indicate the path best we can...
throw JsonMappingException.wrapWithPath(t, bean, _accessorMethod.getName() + "()");
}
}
@Override
public void serializeWithType(Object bean, JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer0)
throws IOException, JsonProcessingException
{
// Regardless of other parts, first need to find value to serialize:
Object value = null;
try {
value = _accessorMethod.invoke(bean);
// and if we got null, can also just write it directly
if (value == null) {
provider.defaultSerializeNull(jgen);
return;
}
JsonSerializer<Object> ser = _valueSerializer;
if (ser == null) { // already got a serializer? fabulous, that be easy...
// ser = provider.findTypedValueSerializer(value.getClass(), true, _property);
ser = provider.findValueSerializer(value.getClass(), _property);
} else {
/* 09-Dec-2010, tatu: To work around natural type's refusal to add type info, we do
* this (note: type is for the wrapper type, not enclosed value!)
*/
if (_forceTypeInformation) {
typeSer0.writeTypePrefixForScalar(bean, jgen);
ser.serialize(value, jgen, provider);
typeSer0.writeTypeSuffixForScalar(bean, jgen);
return;
}
}
/* 13-Feb-2013, tatu: Turns out that work-around should NOT be required
* at all; it would not lead to correct behavior (as per #167).
*/
// and then redirect type id lookups
// TypeSerializer typeSer = new TypeSerializerWrapper(typeSer0, bean);
ser.serializeWithType(value, jgen, provider, typeSer0);
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
Throwable t = e;
// Need to unwrap this specific type, to see infinite recursion...
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors shouldn't be wrapped (and often can't, as well)
if (t instanceof Error) {
throw (Error) t;
}
// let's try to indicate the path best we can...
throw JsonMappingException.wrapWithPath(t, bean, _accessorMethod.getName() + "()");
}
}
@SuppressWarnings("deprecation")
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
throws JsonMappingException
{
if (_valueSerializer instanceof SchemaAware) {
return ((SchemaAware)_valueSerializer).getSchema(provider, null);
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>, Object delegate)
throws IOException, JsonProcessingException
{
if (_delegateCreator == null) { // sanity-check; caller should check
throw new IllegalStateException("No delegate constructor for "+getValueTypeDesc());
}
try {
// First simple case: just delegate, no injectables
if (_delegateArguments == null) {
return _delegateCreator.call1(delegate);
}
// And then the case with at least one injectable...
final int len = _delegateArguments.length;
Object[] args = new Object[len];
for (int i = 0; i < len; ++i) {
CreatorProperty prop = _delegateArguments[i];
if (prop == null) { // delegate
args[i] = delegate;
} else { // nope, injectable:
args[i] = ctxt.findInjectableValue(prop.getInjectableValueId(), prop, null);
}
}
// and then try calling with full set of arguments
return _delegateCreator.call(args);
} catch (ExceptionInInitializerError e) {
throw wrapException(e);
} catch (Exception e) {
throw wrapException(e);
}
}
/*
/**********************************************************
/* Public API implementation; instantiation from JSON scalars
/**********************************************************
*/
@Override
public Object createFromString(DeserializationContext ctxt, String value)
throws IOException, JsonProcessingException
{
if (_fromStringCreator != null) {
try {
return _fromStringCreator.call1(value);
} catch (Exception e) {
throw wrapException(e);
} catch (ExceptionInInitializerError e) {
throw wrapException(e);
}
}
return _createFromStringFallbacks(ctxt, value);
}
@Override
public Object createFromInt(DeserializationContext ctxt, int value)
throws IOException, JsonProcessingException
{
try {
// First: "native" int methods work best:
if (_fromIntCreator != null) {
return _fromIntCreator.call1(Integer.valueOf(value));
}
// but if not, can do widening conversion
if (_fromLongCreator != null) {
return _fromLongCreator.call1(Long.valueOf(value));
}
} catch (Exception e) {
throw wrapException(e);
} catch (ExceptionInInitializerError e) {
throw wrapException(e);
}
throw ctxt.mappingException("Can not instantiate value of type "+getValueTypeDesc()
+" from Integral number ("+value+"); no single-int-arg constructor/factory method");
}
@Override
public Object createFromLong(DeserializationContext ctxt, long value)
throws IOException, JsonProcessingException
{
try {
if (_fromLongCreator != null) {
return _fromLongCreator.call1(Long.valueOf(value));
}
} catch (Exception e) {
throw wrapException(e);
} catch (ExceptionInInitializerError e) {
throw wrapException(e);
}
throw ctxt.mappingException("Can not instantiate value of type "+getValueTypeDesc()
+" from Long integral number ("+value+"); no single-long-arg constructor/factory method");
}
@Override
public Object createFromDouble(DeserializationContext ctxt, double value)
throws IOException, JsonProcessingException
{
try {
if (_fromDoubleCreator != null
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>) {
return _fromDoubleCreator.call1(Double.valueOf(value));
}
} catch (Exception e) {
throw wrapException(e);
} catch (ExceptionInInitializerError e) {
throw wrapException(e);
}
throw ctxt.mappingException("Can not instantiate value of type "+getValueTypeDesc()
+" from Floating-point number ("+value+"); no one-double/Double-arg constructor/factory method");
}
@Override
public Object createFromBoolean(DeserializationContext ctxt, boolean value)
throws IOException, JsonProcessingException
{
try {
if (_fromBooleanCreator != null) {
return _fromBooleanCreator.call1(Boolean.valueOf(value));
}
} catch (Exception e) {
throw wrapException(e);
} catch (ExceptionInInitializerError e) {
throw wrapException(e);
}
throw ctxt.mappingException("Can not instantiate value of type "+getValueTypeDesc()
+" from Boolean value ("+value+"); no single-boolean/Boolean-arg constructor/factory method");
}
/*
/**********************************************************
/* Extended API: configuration mutators, accessors
/**********************************************************
*/
@Override
public AnnotatedWithParams getDelegateCreator() {
return _delegateCreator;
}
@Override
public AnnotatedWithParams getDefaultCreator() {
return _defaultCreator;
}
@Override
public AnnotatedWithParams getWithArgsCreator() {
return _withArgsCreator;
}
@Override
public AnnotatedParameter getIncompleteParameter() {
return _incompleteParameter;
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
protected JsonMappingException wrapException(Throwable t)
{
while (t.getCause() != null) {
t = t.getCause();
}
if (t instanceof JsonMappingException) {
return (JsonMappingException) t;
}
return new JsonMappingException("Instantiation of "+getValueTypeDesc()+" value failed: "+t.getMessage(), t);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind;
import java.lang.annotation.Annotation;
import java.util.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.core.Versioned;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.deser.ValueInstantiator;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
import com.fasterxml.jackson.databind.util.Converter;
import com.fasterxml.jackson.databind.util.NameTransformer;
/**
* Abstract class that defines API used for introspecting annotation-based
* configuration for serialization and deserialization. Separated
* so that different sets of annotations can be supported, and support
* plugged-in dynamically.
*<p>
* NOTE: due to rapid addition of new methods (and changes to existing methods),
* it is <b>strongly</b> recommended that custom implementations should not directly
* extend this class, but rather extend {@link NopAnnotationIntrospector}.
* This way added methods will not break backwards compatibility of custom annotation
* introspectors.
*/
@SuppressWarnings("serial")
public abstract class AnnotationIntrospector
implements Versioned, java.io.Serializable
{
/*
/**********************************************************
/* Helper types
/**********************************************************
*/
/**
* Value type used with managed and back references; contains type and
* logic name, used to link related references
*/
public static class ReferenceProperty
{
public enum Type {
/**
* Reference property that Jackson manages and that is serialized normally (by serializing
* reference object), but is used for resolving back references during
* deserialization.
* Usually this can be defined by using
* {@link com.fasterxml.jackson.annotation.JsonManagedReference}
*/
MANAGED_REFERENCE
/**
* Reference property that Jackson manages by suppressing it during serialization,
* and reconstructing during deserialization.
* Usually this can be defined by using
* {@link com.fasterxml.jackson.annotation.JsonBackReference}
*/
,BACK_REFERENCE
;
}
private final Type _type;
private final String _name;
public ReferenceProperty(Type t, String n) {
_type = t;
_name = n;
}
public static ReferenceProperty managed(String name) { return new ReferenceProperty(Type.MANAGED_REFERENCE, name); }
public static ReferenceProperty back(String name) { return new ReferenceProperty(Type.BACK_REFERENCE, name); }
public Type getType() { return _type; }
public String getName() { return _name; }
public boolean isManagedReference() { return _type == Type.MANAGED_REFERENCE; }
public boolean isBackReference() { return _type == Type
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.BeanDeserializer;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.util.NameTransformer;
/**
* Deserializer that builds on basic {@link BeanDeserializer} but
* override some aspects like instance construction.
*/
public class ThrowableDeserializer
extends BeanDeserializer
{
private static final long serialVersionUID = 1L;
protected final static String PROP_NAME_MESSAGE = "message";
/*
/************************************************************
/* Construction
/************************************************************
*/
public ThrowableDeserializer(BeanDeserializer baseDeserializer) {
super(baseDeserializer);
// need to disable this, since we do post-processing
_vanillaProcessing = false;
}
/**
* Alternative constructor used when creating "unwrapping" deserializers
*/
protected ThrowableDeserializer(BeanDeserializer src, NameTransformer unwrapper) {
super(src, unwrapper);
}
@Override
public JsonDeserializer<Object> unwrappingDeserializer(NameTransformer unwrapper) {
if (getClass() != ThrowableDeserializer.class) {
return this;
}
/* main thing really is to just enforce ignoring of unknown
* properties; since there may be multiple unwrapped values
* and properties for all may be interleaved...
*/
return new ThrowableDeserializer(this, unwrapper);
}
/*
/************************************************************
/* Overridden methods
/************************************************************
*/
@Override
public Object deserializeFromObject(JsonParser jp, DeserializationContext ctxt) throws IOException
{
// 30-Sep-2010, tatu: Need to allow use of @JsonCreator, so:
if (_propertyBasedCreator != null) { // proper @JsonCreator
return _deserializeUsingPropertyBased(jp, ctxt);
}
if (_delegateDeserializer != null) {
return _valueInstantiator.createUsingDelegate(ctxt,
_delegateDeserializer.deserialize(jp, ctxt));
}
if (_beanType.isAbstract()) { // for good measure, check this too
throw JsonMappingException.from(jp, "Can not instantiate abstract type "+_beanType
+" (need to add/enable type information?)");
}
boolean hasStringCreator = _valueInstantiator.canCreateFromString();
boolean hasDefaultCtor = _valueInstantiator.canCreateUsingDefault();
// and finally, verify we do have single-String arg constructor (if no @JsonCreator)
if (!hasStringCreator && !hasDefaultCtor) {
throw new JsonMappingException("Can not deserialize Throwable of type "+_beanType
+" without having a default contructor, a single-String-arg constructor; or explicit @JsonCreator");
}
Object throwable = null;
Object[] pending = null;
int pendingIx = 0;
for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) {
String propName = jp.getCurrentName();
SettableBeanProperty prop = _beanProperties.find(propName);
jp.nextToken(); // to point to field value
if (prop != null) { // normal case
if (throwable != null) {
prop.deserializeAndSet(jp,
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Node that maps to JSON Object structures in JSON content.
*<p>
* Note: class was <code>final</code> temporarily for Jackson 2.2.
*/
public class ObjectNode
extends ContainerNode<ObjectNode>
{
// Note: LinkedHashMap for backwards compatibility
protected final Map<String, JsonNode> _children;
public ObjectNode(JsonNodeFactory nc) {
super(nc);
_children = new LinkedHashMap<String, JsonNode>();
}
/**
* @since 2.4
*/
public ObjectNode(JsonNodeFactory nc, Map<String, JsonNode> kids) {
super(nc);
_children = kids;
}
@Override
protected JsonNode _at(JsonPointer ptr) {
return get(ptr.getMatchingProperty());
}
/* Question: should this delegate to `JsonNodeFactory`? It does not absolutely
* have to, as long as sub-types override the method but...
*/
// note: co-variant for type safety
@SuppressWarnings("unchecked")
@Override
public ObjectNode deepCopy()
{
ObjectNode ret = new ObjectNode(_nodeFactory);
for (Map.Entry<String, JsonNode> entry: _children.entrySet())
ret._children.put(entry.getKey(), entry.getValue().deepCopy());
return ret;
}
/*
/**********************************************************
/* Implementation of core JsonNode API
/**********************************************************
*/
@Override
public JsonNodeType getNodeType() {
return JsonNodeType.OBJECT;
}
@Override public JsonToken asToken() { return JsonToken.START_OBJECT; }
@Override
public int size() {
return _children.size();
}
@Override
public Iterator<JsonNode> elements() {
return _children.values().iterator();
}
@Override
public JsonNode get(int index) { return null; }
@Override
public JsonNode get(String fieldName) {
return _children.get(fieldName);
}
@Override
public Iterator<String> fieldNames() {
return _children.keySet().iterator();
}
@Override
public JsonNode path(int index) {
return MissingNode.getInstance();
}
@Override
public JsonNode path(String fieldName)
{
JsonNode n = _children.get(fieldName);
if (n != null) {
return n;
}
return MissingNode.getInstance();
}
/**
* Method to use for accessing all fields (with both names
* and values) of this JSON Object.
*/
@Override
public Iterator<Map.Entry<String, JsonNode>> fields() {
return _children.entrySet().iterator();
}
@Override
public ObjectNode with(String propertyName) {
JsonNode n = _children.get
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS> {
foundSoFar = new ArrayList<JsonNode>();
}
foundSoFar.add(this);
} else { // only add children if parent not added
foundSoFar = entry.getValue()
.findParents(fieldName, foundSoFar);
}
}
return foundSoFar;
}
/*
/**********************************************************
/* Public API, serialization
/**********************************************************
*/
/**
* Method that can be called to serialize this node and
* all of its descendants using specified JSON generator.
*/
@Override
public void serialize(JsonGenerator jg, SerializerProvider provider)
throws IOException, JsonProcessingException
{
jg.writeStartObject();
for (Map.Entry<String, JsonNode> en : _children.entrySet()) {
jg.writeFieldName(en.getKey());
/* 17-Feb-2009, tatu: Can we trust that all nodes will always
* extend BaseJsonNode? Or if not, at least implement
* JsonSerializable? Let's start with former, change if
* we must.
*/
((BaseJsonNode) en.getValue()).serialize(jg, provider);
}
jg.writeEndObject();
}
@Override
public void serializeWithType(JsonGenerator jg, SerializerProvider provider,
TypeSerializer typeSer)
throws IOException, JsonProcessingException
{
typeSer.writeTypePrefixForObject(this, jg);
for (Map.Entry<String, JsonNode> en : _children.entrySet()) {
jg.writeFieldName(en.getKey());
((BaseJsonNode) en.getValue()).serialize(jg, provider);
}
typeSer.writeTypeSuffixForObject(this, jg);
}
/*
/**********************************************************
/* Extended ObjectNode API, mutators, since 2.1
/**********************************************************
*/
/**
* Method that will set specified field, replacing old value, if any.
* Note that this is identical to {@link #replace(String, JsonNode)},
* except for return value.
*<p>
* NOTE: added to replace those uses of {@link #put(String, JsonNode)}
* where chaining with 'this' is desired.
*
* @param value to set field to; if null, will be converted
* to a {@link NullNode} first (to remove field entry, call
* {@link #remove} instead)
*
* @return This node after adding/replacing property value (to allow chaining)
*
* @since 2.1
*/
public JsonNode set(String fieldName, JsonNode value)
{
if (value == null) {
value = nullNode();
}
_children.put(fieldName, value);
return this;
}
/**
* Method for adding given properties to this object node, overriding
* any existing values for those properties.
*
* @param properties Properties to add
*
* @return This node after adding/replacing property values (to allow chaining)
*
* @since 2.1
*/
public JsonNode setAll(Map<String,? extends JsonNode> properties)
{
for (Map.Entry<String,? extends JsonNode> en : properties.entrySet()) {
JsonNode n = en.getValue();
if (n == null) {
n = nullNode();
}
_children.put(
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.node;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.io.NumberOutput;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* Numeric node that contains 64-bit ("double precision")
* floating point values simple 32-bit integer values.
*/
public class DoubleNode
extends NumericNode
{
protected final double _value;
/*
/**********************************************************
/* Construction
/**********************************************************
*/
public DoubleNode(double v) { _value = v; }
public static DoubleNode valueOf(double v) { return new DoubleNode(v); }
/*
/**********************************************************
/* BaseJsonNode extended API
/**********************************************************
*/
@Override public JsonToken asToken() { return JsonToken.VALUE_NUMBER_FLOAT; }
@Override
public JsonParser.NumberType numberType() { return JsonParser.NumberType.DOUBLE; }
/*
/**********************************************************
/* Overrridden JsonNode methods
/**********************************************************
*/
@Override
public boolean isFloatingPointNumber() { return true; }
@Override
public boolean isDouble() { return true; }
@Override public boolean canConvertToInt() {
return (_value >= Integer.MIN_VALUE && _value <= Integer.MAX_VALUE);
}
@Override public boolean canConvertToLong() {
return (_value >= Long.MIN_VALUE && _value <= Long.MAX_VALUE);
}
@Override
public Number numberValue() {
return Double.valueOf(_value);
}
@Override
public short shortValue() { return (short) _value; }
@Override
public int intValue() { return (int) _value; }
@Override
public long longValue() { return (long) _value; }
@Override
public float floatValue() { return (float) _value; }
@Override
public double doubleValue() { return _value; }
@Override
public BigDecimal decimalValue() { return BigDecimal.valueOf(_value); }
@Override
public BigInteger bigIntegerValue() {
return decimalValue().toBigInteger();
}
@Override
public String asText() {
return NumberOutput.toString(_value);
}
@Override
public final void serialize(JsonGenerator jg, SerializerProvider provider)
throws IOException, JsonProcessingException
{
jg.writeNumber(_value);
}
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o instanceof DoubleNode) {
// We must account for NaNs: NaN does not equal NaN, therefore we have
// to use Double.compare().
final double otherValue = ((DoubleNode) o)._value;
return Double.compare(_value, otherValue) == 0;
}
return false;
}
@Override
public int hashCode()
{
// same as hashCode Double.class uses
long l = Double.doubleToLongBits(_value);
return ((int) l) ^ (int) (l >> 32);
}
}
JacksonDatabind, 7
<FILEB>
<CHANGES>
if (jp.getCurrentTokenId()!= JsonToken.FIELD_NAME.id()) {
<CHANGEE>
<CHANGES>
return this;
}
<CHANGEE>
<CHANGES>
JsonToken t;
writeStartObject();
do {
copyCurrentStructure(jp);
} while ((t = jp.nextToken()) == JsonToken.FIELD_NAME);
if (t!= JsonToken.END_OBJECT) {
throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t);
}
writeEndObject();
<CHANGEE>
<FILEE>
<FILEB>
case VALUE_NULL:
jgen.writeNull();
break;
case VALUE_EMBEDDED_OBJECT:
jgen.writeObject(segment.get(ptr));
break;
default:
throw new RuntimeException("Internal error: should never end up through this code path");
}
}
}
/**
* Helper method used by standard deserializer.
*
* @since 2.3
*/
public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
<CHANGES>
<CHANGEE>
copyCurrentStructure(jp);
<CHANGES>
<CHANGEE>
/* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from
* FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need
* to assume one did exist.
*/
<CHANGES>
<CHANGEE>
return this;
}
@Override
@SuppressWarnings("resource")
public String toString()
{
// Let's print up to 100 first tokens...
final int MAX_COUNT = 100;
StringBuilder sb = new StringBuilder();
sb.append("[TokenBuffer: ");
/*
sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(",");
<FILEE>
<SCANS>
mapper.setInjectableValues(new InjectableValues.Std()
.addValue(String.class, "Fygar")
);
FactoryBean711 bean = null;
try {
bean = mapper.readValue("38", FactoryBean711.class);
} catch (JsonMappingException e) {
fail("Did not expect problems, got: "+e.getMessage());
}
assertEquals(38, bean.age);
assertEquals("Fygar", bean.name1);
assertEquals("Fygar", bean.name2);
}
// [databind#592]
public void testDelegateWithTokenBuffer() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
Value592 value = mapper.readValue("{\"a\":1,\"b\":2}", Value592.class);
assertNotNull(value);
Object ob = value.stuff;
assertEquals(TokenBuffer.class, ob.getClass());
JsonParser jp = ((TokenBuffer) ob).asParser();
assertToken(JsonToken.START_OBJECT, jp.nextToken());
assertToken(JsonToken.FIELD_NAME, jp.nextToken());
assertEquals("a", jp.getCurrentName());
assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
assertEquals(1, jp.getIntValue());
assertToken(JsonToken.FIELD_NAME, jp.nextToken());
assertEquals("b", jp.getCurrentName());
assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
assertEquals(2, jp.getIntValue());
assertToken(JsonToken.END_OBJECT, jp.nextToken());
jp.close();
}
}